Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does SecurityContext#setAuthentication guaranties visibility?

Tags:

I use spring security in my project.

I have feature to change login. To achieve this aim I use following code

Authentication authentication = ... SecurityContextHolder.getContext().setAuthentication(authentication); 

But now I am resesarching this code in details and see that authentication field is not volatile thus visibility is not guaranteed:

 public class SecurityContextImpl implements SecurityContext {      private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;      // ~ Instance fields     // ================================================================================================      private Authentication authentication; 

Should I wrap my code with my own synchronization to achieve visibility?

P.S.

I have read https://stackoverflow.com/a/30781541/2674303

In an application which receives concurrent requests in a single session, the same SecurityContext instance will be shared between threads. Even though a ThreadLocal is being used, it is the same instance that is retrieved from the HttpSession for each thread. This has implications if you wish to temporarily change the context under which a thread is running. If you just use SecurityContextHolder.getContext(), and call setAuthentication(anAuthentication) on the returned context object, then the Authentication object will change in all concurrent threads which share the same SecurityContext instance. You can customize the behaviour of SecurityContextPersistenceFilter to create a completely new SecurityContext for each request, preventing changes in one thread from affecting another. Alternatively you can create a new instance just at the point where you temporarily change the context. The method SecurityContextHolder.createEmptyContext() always returns a new context instance.

but I don't understand how spring does guaranties visibility. There are just written that each thread within session will see changes. but there is no answer how fast? and more important - visibility mechanism is not explained

like image 677
gstackoverflow Avatar asked Sep 19 '17 14:09

gstackoverflow


People also ask

What is SecurityContext in Kubernetes?

A security context defines privilege and access control settings for a Pod or Container. Security context settings include, but are not limited to: Discretionary Access Control: Permission to access an object, like a file, is based on user ID (UID) and group ID (GID).

What is the use of fsGroup?

The fsGroup setting defines a group which Kubernetes will change the permissions of all files in volumes to when volumes are mounted by a pod. The behavior here is also controlled by the fsGroupChangePolicy , which can be set to onRootMismatch or Always .

What is runAsNonRoot?

The Kubernetes Pod SecurityContext provides two options runAsNonRoot and runAsUser to enforce non root users. You can use both options separate from each other because they test for different configurations. When you set runAsNonRoot: true you require that the container will run with a user with any UID other than 0.

How do I run pods in privileged mode?

Running a pod in a privileged mode means that the pod can access the host's resources and kernel capabilities. You can turn a pod into a privileged one by setting the privileged flag to `true` (by default a container is not allowed to access any devices on the host).


1 Answers

Your doubts are justified, visibility is not guaranteed. ThreadLocal isn't thread-safe, when all ThreadLocalMap's entries store the same object.

Referenced documentation part, Storing the SecurityContext between requests, warns you about that fact and proposes possible solutions to change the context in a way, that prevents affect on other threads.

An example of such solution is the RunAs mechanism, which changes the context during the secure object callback phase.

But, as I understand your question, you need to change the user's login (i.e. username) "on the fly". If I'm right, then the problem is, when you'd set a modified Authentication - another thread could read the old value. To avoid this race condition you need to make a login write happens-before every sequential login read.

Authentication interface has the getPrincipal() method, which returns an Object, which is an UserDetails instance (in most cases). This object is usually used to obtain a username for the current (authenticated) user.

So, if you want to change the login for authenticated user "on the fly", you can modify the username property in this UserDetails object.

Possible way to make it in a thread-safe manner is a custom UserDetails implementation with the volatile String username property (default User implementation has an immutable username).

You should also create and wire into your configuration an UserDetailsService implementation, which will use your custom UserDetails.

like image 103
Anatoly Shamov Avatar answered Oct 02 '22 18:10

Anatoly Shamov