Trying to integrate Spring Session into a grails app. Successfully have gotten the sessions to persist on the back end and now I am looking at trying to manually expire sessions.
The problem is when I expire a session manually as shown below. I am not logged out of the application. Further more, when I interrogate the session object, it thinks that it is not expired.
Am I doing something wrong?
// Gets my user
def user = ctx.springSecurityService.getPrincipal()
// Gets my current session
SpringSessionBackedSessionInformation session = ctx.sessionRegistry.getAllSessions(user, false)[0]
// Expires my session (Can see change in database)
session.expireNow()
// returns false. When I look at the code for the method it is only checking if the session has
// expired due to a timeout
session.session.isExpired()
I tried looking through the docs on Spring Session for Expiry and didn't see anything for JDBC specifically. Thought I'd post it to see if anyone out there is well versed in Spring Session.
Related
I am working on a java application using spring security.
I want to avoid the session fixation, but the session fixation solution found on the docs seem not to be working as expected... here
So, I did this on my login
final HttpSession session = request.getSession(false);
if (session != null && !session.isNew()) {
session.invalidate();
}
Works great and changes the JSESSIONID everytime I call the login page...
But once I am logged in, I can call the login page again, get another JSESSIONID and still be logged in, I can just click on the back button and come back to the logged users area.
It does change the JSESSIONID, my question is, shouldnt it have a bigger effect? like invalidate my session or log me out?
When I call the log out form it does log the user out and works as expected, I am just wondering if changing the JSESSIONID has a real effect or does nto matter.
ANy idea?
I am using security 3.2
spring's session is mapped to JSESSIONID. so if a customer would have session state beans, they would be lost after changing JSESSIONID.
even though documentation tells
Spring Security protects against this automatically by creating a new
session when a user logs in
you can explicitly set configuration for session fixation by adding this
<security:session-management session-authentication-strategy-ref="fixation" />
and defining fixation bean with SessionFixationProtectionStrategy class
I have created a basic spring security authentication using UserDetailsService and now I am able to validate user. However, I don't understand how to achieve below things:
Once a user is logged in, when next request comes how and where do I check if the request is coming from the same logged in user or other logged in user?
I know the concept of Spring interceptors where I can intercept all incoming request. But is there something in spring security that does this?
How can I start a session after logging in and store values in session for that user?
I browsed through existing answers but most of examples are for logging in.
I would appreciate if someone can give me examples.
EDIT:
I think I should use session scoped beans in order to maintain user's session contents rather than manipulating httpsession directly.
I think you really need to spend some time reading the Spring security documentation and over all JSP, servlet and MVC architecture. You have several misunderstandings,
After authentication, you don't need to start a session it was already there when the request came. Remember request.getSession()we get the session from the request and I am really NOT aware of any other way i.e. instantiating session object and assigning it to request/response. After successful authentication spring automatically sets a SPRING_SECURITY_CONTEXT attribute in session and this variable is later used to determine whether user is already authenticated or not (Spring does that for you, you don't need to use this attribute).
In spring security we set an authentication entry point which has information about login page url and FORM_LOGIN_FILTER which has information about login processing url, login success url and login failure url among few other things.Every request whose session doesn't have SPRING_SECURITY_CONTEXT and auth attribute gets redirected to login page url.
I could give the code directly but it would be great if you read at least few pages of Spring documentation here. Once you understand the concepts and are still not able to solve the problem. Edit your question with detailed problem and we will try to fix it.
At first you need to create an Authentication object using current HttpRequest as below:
public class SessionService{
public Authentication getSession(HttpServletRequest request) {
HttpSession session=request.getSession();
SecurityContext ctx= (SecurityContext) session.getAttribute("SPRING_SECURITY_CONTEXT");
Authentication auth=ctx.getAuthentication();
return auth;
}
}
Then, you can retrieve the session details from this Authentication object by passing the current HttpRequest as follows:
Authentication auth = sessionService.getSession(request);
The above auth object contains the details that you need.
In my grails application running on tomcat 7, Somewhere I am invalidating the existing http session (session.invalidate()) and creating a new session (request.getSession(true)).
But my this new session is not getting reflected everywhere in grails application. Due to this I do get 'Session already invalidated'.
I don't want to do request.getSession() everywhere. I am just using 'session'.
Is there anything in Grails 1.3.7, so that this new session gets reflected every where in app.
Please let me know if you need more info.
Regards
Well, Grails holds the reference to a session object and every time you ask it for a session it returns the same reference.. so if you invalidate a session and then ask for the session it will return the same invalidated session, and cause 'session already invalidated' exception..
This should work for you..
Execute following line Just after you do session.invalidate
//Trick - so that grails doesn't use old invalidated session but rather create new.
GrailsWebRequest.lookup(request).session = null
After that you can use session just as you do normally.. you dont need to create a new session yourself
See this thread for internals
A new corporate policy on Secure Coding was recently put into effect. The initial audit assessment tagged me deficient for:
Session state must be managed such that a session will withstand replay-attacks.
I'm not exactly sure what this statement means or why I am defecient in it. I'm developing a Java Web application and set a session as such:
session.setMaxInactiveInterval(36000);
Session state must be managed such that a session will withstand replay-attacks.
The statement is way too confusing. Rewording it would yield:
The session management framework must protect the application against replay of session IDs.
It is less confusing (hopefully), and continues to carry the same meaning as the former (again, hopefully).
Typically, if one were to implement a home-grown session management framework instead of relying on the one provided by the container for instance, then it is quite possible that the session management feature of the application would be susceptible to a replay attack.
A session replay attack would involve the scenario where the session ID is replayed back in a request, after the session has expired. A well written session management framework would recognize that the provided session ID is not a valid session ID. However, there have been instances where a vulnerable session management framework accepted the now-expired session ID, and recreated the contents of the session. In worser scenarios, the session management framework did not destroy the session at all, on session expiry, resulting in the scenario where a session ID replay resulting in requests being processed.
It must be remembered that even normal users of the application may unintentionally perform session-replay attacks, if they are able to browse to protected pages in the application without logging in. This is an indication of a failure in the authentication and the session management features of the application, for the app should ideally allow users to browse protected pages only after successful authentication, which would yield a token (a session ID) that may be used for a certain duration to access the site without further authentication. If you are using persistent cookies for authentication, you may have unintentionally introduced a hole.
Going by the above, one can protect any application from session replay attacks by:
Ensure that you are using the container provided session management features. From the use of the session.setMaxInactiveInterval I would assume that you are it. But, to be sure, verify if you are creating session IDs using other means, or for that matter, verify if you are using identifiers that are equivalent to session IDs. In simpler words, ensure that your application relies only on the value of the JSESSIONID cookie (or the equivalent as configured in the container) to communicate session IDs to the browser. Also, verify if persistent cookie are in use (refer the above posted scenario).
Invalidate the session after a certain idle period. If you do not invalidate the session, then an attacker has a larger time window to brute force the session ID. From the point of view of session-replay attacks, this is worse since the attacker can replay back a compromised session ID at any point in time, and still get access to a valid user session. You would also want to revisit the duration specified in the session.setMaxInactiveInterval for the value you are using currently is 10 hours. I would consider that to be insecure. Most applications do not require a rolling window of session expiry beyond 30 minutes, with 10 minutes being the value recommended for high-value apps.
Destroy the server-side session and it's contents on expiry. In a servlet container, this is typically done by invoking session.invalidate() in a logout page/link. Ensure that you have provided users with a link to logout from the application in the first place, so that the logout request can be processed to invalidate the session using the before-mentioned API call. If you do not perform this activity, the server-side session object will be destroyed only on session expiry (which will occur after 10 hours of inactivity by the user; now you see why 10 hours is a bad idea).
this is to do with something similar to session hijacking.. where the auth token is held by a hacker to login at a later stage..
in my projects i've added a simple filter which does the following.
every jsp page which is responded would be given an attribute called id (the token is generated using UUID().. the same token is placed in the session..
when a page is posted, the filter (which is configured to filter all requests) checks for the equality of these tokens & proceeds only if the values match.
we also added a timestamp in the session & the database, whenever a page is submitted we check the time stamps in the session with the db.. if the number is within 10 ms then the request passes, else the user is redirected...
I am using Spring Security 3.0 and created a custom filter to check for expired sessions.
My problem is that request.isRequestedSessionValid() returns true in my filter even after I let the session expire or log out. If I try to access any secured page, I do get redirected to my login page so I know that the session management works.
My understanding was that when a web session times out, the session is automatically invalidated and I also set invalidate-session in my logout element of Spring Security. How can the session still be valid? Am I checking the wrong value?
request.isRequestedSessionValid() can itself cause a session to be created, even after logout has been called. Use request.getSession(false) != null to check instead, which will ensure that a session is not created.