How Spring Security get currently logged in user in concept? - spring

I get the currently logged in user by
SecurityContextHolder.getContext().getAuthentication() in server side and do some logging on users.
Here is the question:
Suppose I have three user logged in.
How the server side can identify the user just simply calling SecurityContextHolder.getContext().getAuthentication(); ?
Thanks for your reply.

By default there are 3 important things here:
HTTP session - stores authentication object between requests
Servlet API filter - populates SecurityContextHolder before each request from HTTP session (and stores authentication object back once the request has completed)
ThreadLocal - stores authentication object during request processing
After authentication corresponding SecurityContext object is stored in HTTP session.
Before each request processing special SecurityContextPersistenceFilter is fired. It is responsible for loading of SecurityContext object from HTTP session (via SecurityContextRepository instance) and for injecting SecurityContext object into SecurityContextHolder. Take a look at the source code of SecurityContextPersistenceFilter class for more details. Another important part is that by default SecurityContextHolder stores SecurityContext object using ThreadLocal variable (so you will have a different authentication object per thread).
EDIT. Additional questions:
HTTP session is saved in client's browser and updated between requests. No, HTTP session is stored in server side. It is linked to some user via session coockie (browser send this cookie during each request).
SecurityContext, SecurityContextHolder and SecurityContextRepository are instances in Server side. They are used on server side. But SecurityContextHolder is not an instance, it is a helper class with static methods.
ThreadLocal is a variable storing SecurityContextHolder which stores SecurityContext No, SecurityContext is stored in ThreadLocal variable. SecurityContextHolder is a helper class that may be used to get/set SecurityContext instance via ThreadLocal variable.
If there are three connections, then there will be three SecurityContext object in Server. Yep.
One SecurityContextHolder stores one SecurityContext No, the same static methods of SecurityContextHolder used by all threads to get/set corresponding SecurityContext.
And suppose there are three SecurityContext instances in Server Side, how does it knows which one refers to that corresponding client? ThreadLocal variable has different values for different threads.

For every logged-in user, there will be different sessions. Every session have its own configuration. Therefore, at server side, SecurityContext load data specific to a session. You can visualise data in SecurityContext as a map(key-value) pair.

Related

How does spring security maintain authentication information between request?

How does spring security maintain authentication info between requests?
Does it use any thing similar to jSessionId or uses an entirely different mechanism.
Further, I see that the AbstractSecurityInterceptor (I mean, any of it's implementations) is responsible for intercepting the incoming request and verify if a request is already authorized using Authentication.isAuthenticated() and then depending on the condition either validate the request or send the Authentication request to an AuthenticationManager Implementation. So, in other words, how does AbstractSecurityInterceptor differentiate between first request and subsequent request.
Spring Security uses a SecurityContextRepository to store and retrieve the SecurityContext for the current security session.
The default implementation is the HttpSessionSecurityContextRepository which utilizes the javax.servlet.http.HttpSession to store/retrieve the SecurityContext.
The underlying servlet container will obtain the correct HttpSession for the incoming request, generally due to a session identifier being passed in a cookie or request parameter. For Spring Security it doesn't matter as that is thus loaded of to the underlying servlet container.

what is the filter responsible for keeping the authentication object in security context in spring security

to my knowledge the most of the authentication filter extends AbstractAuthenticationProcessingFilter and overrides attemptAuthentication method which is called in dofilter method but i do not see how the authentication object is placed in securitycontext because the sessionstrategy in abstractauthenticationprocessinfilter is set to NullAuthenticatedSessionStrategy which does not do any thing in onAuthentication method so how does the security exactly work
You are right. AbstractAuthenticationProcessingFilter is responsible for placing Authentication to the SecurityContext.It is done inside successfulAuthentication(). Its javadoc also states such behaviour :
Default behaviour for successful authentication.
Sets the successful Authentication object on the SecurityContextHolder
Informs the configured RememberMeServices of the successful login
Fires an InteractiveAuthenticationSuccessEvent via the configured ApplicationEventPublisher
Delegates additional behaviour to the AuthenticationSuccessHandler.
The SessionAuthenticationStrategy you mentioned (which is set to NullAuthenticatedSessionStrategy by default) is for plugging other HttpSession-related behaviour when authentication occurs such as to ensure session exists or guard against session-fixation attacks. The default behaviour (i.e. successfulAuthentication()) will always run no matter what strategy it is set to.

Spring Security Sequence of execution

I am not able to find out where and when exactly the authentication manager is executed by spring security. I mean there are certian filters which are executed sequentially as below:
FIRST
- CHANNEL_FILTER
- CONCURRENT_SESSION_FILTER
- SECURITY_CONTEXT_FILTER
- LOGOUT_FILTER
- X509_FILTER
- PRE_AUTH_FILTER
- CAS_FILTER
- FORM_LOGIN_FILTER
- OPENID_FILTER
- BASIC_AUTH_FILTER
- SERVLET_API_SUPPORT_FILTER
- REMEMBER_ME_FILTER
- ANONYMOUS_FILTER
- EXCEPTION_TRANSLATION_FILTER
- SESSION_MANAGEMENT_FILTER
- FILTER_SECURITY_INTERCEPTOR
- SWITCH_USER_FILTER
- LAST
But when exactly authentication provider authenticates the provided username and password, i mean to ask after which these below filters is the authentication provider is executed .
Regards
Jayendra
From Spring Security documentation:
The order that filters are defined in the chain is very important.
Irrespective of which filters you are actually using, the order should
be as follows:
ChannelProcessingFilter, because it might need to redirect to a different protocol
SecurityContextPersistenceFilter, so a SecurityContext can be set up in the SecurityContextHolder at the beginning of a web request, and
any changes to the SecurityContext can be copied to the HttpSession
when the web request ends (ready for use with the next web request)
ConcurrentSessionFilter, because it uses the SecurityContextHolder functionality but needs to update the SessionRegistry to reflect
ongoing requests from the principal
Authentication processing mechanisms - UsernamePasswordAuthenticationFilter, CasAuthenticationFilter,
BasicAuthenticationFilter etc - so that the SecurityContextHolder can
be modified to contain a valid Authentication request token
The SecurityContextHolderAwareRequestFilter, if you are using it to install a Spring Security aware HttpServletRequestWrapper into your
servlet container
RememberMeAuthenticationFilter, so that if no earlier authentication processing mechanism updated the SecurityContextHolder,
and the request presents a cookie that enables remember-me services to
take place, a suitable remembered Authentication object will be put
there
AnonymousAuthenticationFilter, so that if no earlier authentication processing mechanism updated the SecurityContextHolder,
an anonymous Authentication object will be put there
ExceptionTranslationFilter, to catch any Spring Security exceptions so that either an HTTP error response can be returned or an
appropriate AuthenticationEntryPoint can be launched
FilterSecurityInterceptor, to protect web URIs and raise exceptions when access is denied
So the authentication manager is called at step 4. If you look at the source code of UsernamePasswordAuthenticationFilter you will see something like:
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
// ...
return this.getAuthenticationManager().authenticate(authRequest);
}

Difference of Spring session management and spring security session?

I am new with spring ,I have a doubt about spring session management and spring security session ,whether both concept are same or different ? If different what are that ? Any suggestion ?
May you be a little bit more specific in your question?
In Spring:
session can refer to one of the scopes that a bean belongs to. For example, if you define an instance (bean) of a class a org.something.Counter with scope session, whenever you will access that bean during a web session you will have the same instance of the object. Web session does not require Spring Security in order to exists. You can start from here to understand a little bit more about the session scope in Spring.
session may refer to HttpSession as speciffied by the Servlet API. This is not really related to Spring, even if you can use the standard HttpSession from within Spring, is more in general related to the Servlet API.
In Spring Security:
If you are talking of Spring Security, instead of session I would talk of SecurityContext. The SecurityContext is actually stored as an HttpSession and restored to the SecurityContextHolder at every request. Here is were all security-related infos are stored for the current session. See here for more details. In general a SecurityContext (at least at a very basic level) exists from the moment you login to the moment you logout. Because it is stored as an HttpSession it expires when the HttpSession expires (again, see the Servlet API specifications for more details)
Luca

Creating a session cookie inside a controller

I'm new to Tomcat, servlets and Spring Web. I'm coming from a PHP background so I'm a little disoriented to say the least. I want a controller to create a session cookie for me.
I've been told that I can get the session like this in a standard servlet:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Somewhere inside the method...
HttpSession session = request.getSession(true);
// Set a cookie
session.setAttribute("hello", "world");
// More stuff...
}
How does this translate into the Spring Web MVC way of doing things? Can I create session cookies inside a controller?
What you are doing in your example have nothing to do with cookies.
session.setAttribute("key", valueObject);
Sets a java-object in the session. The session is kept at the server. The sessionid is the only thing communicated back to the client. It can be a cookie or it can be in the URL. The attributes in the session is not serialized to strings.
Cookies on the other hand are strings that are sent back to the client. It is the clients responsibility to store their cookies (and some people turn them off) and return them to the server.
Setting a cookie value from a complex object-graph will require serialization and deserialization. A session attribute will not.
If you want to read a cookie, use this:
#CookieValue("key") String cookie
In the controller parameter list. The cookie variable will be populated with the value from the cookie named "key".
To set a cookie, call:
response.addCookie(cookie);
In Java Servlets (and Spring MVC in particular) you don't interact with session cookie directly, actually properly written servlet based application should work without cookies enabled, automatically falling back to URL based session id.
The way you provided is correct, although Spring is giving you much better (higher level) approaches like session-scoped beans. This way you never interact with the session itself.
You can get access to the HttpSession object by including it as a parameter in your controller's method(s):
public String get(Long id, HttpSession session) {
}
Spring will inject the current HttpSession object for you, and from there you can set attributes (like you did in your question).

Resources