views:

4830

answers:

5

I am using Wicket with the Wicket Auth Project for my presentation layer and I have therefore integrated it with Spring Security. This is the method which is called by Wicket for authentication for me:

@Override
public boolean authenticate(String username, String password) {
    try {
     Authentication request = new UsernamePasswordAuthenticationToken(
       username, password);
     Authentication result = authenticationManager.authenticate(request);
     SecurityContextHolder.getContext().setAuthentication(result);
    } catch (AuthenticationException e) {
     return false;
    }
    return true;
}

The contents (inside ) of my Spring Security XML configuration are:

<http path-type="regex">
    <form-login login-page="/signin"/>
<logout logout-url="/logout" />
</http>
<global-method-security secured-annotations="enabled" />
<authentication-manager alias="authenticationManager"/>
<authentication-provider user-service-ref="userService">
    <password-encoder ref="bcryptpasswordencoder" />
</authentication-provider>

The section 2.3.6. Session Fixation Attack Protection of the reference documentation says:

Session fixation attacks are a potential risk where it is possible for a malicious attacker to create a session by accessing a site, then persuade another user to log in with the same session (by sending them a link containing the session identifier as a parameter, for example). Spring Security protects against this automatically by creating a new session when a user logs in. If you don't require this protection, or it conflicts with some other requirement, you can control the behaviour using the session-fixation-protection attribute on , which has three options:

  • migrateSession - creates a new session and copies the existing session attributes to the new session. This is the default.
  • none - Don't do anything. The original session will be retained.
  • newSession - Create a new "clean" session, without copying the existing session data.

The authentication works, but I as I'm fairly new to Spring Security I have some questions which I need answers too:

  • Normally for login, I would POST the authentication information to j_spring_security_check and let Spring Security perform the actual authentication code. I would like to have protection against session fixation attacks, will I get it when I perform a programmatic login as I do? And if not, what would I have to do to get it?
  • How do I perform programmatic logout?
  • As I will use programmatic login and logout, how do I disable Spring from intercepting those URL's?

Update: For session fixation attack protection it seems that I need to call the method in the SessionUtils class with the signature startNewSessionIfRequired(HttpServletRequest request, boolean migrateAttributes, SessionRegistry sessionRegistry).

How do I get the SessionRegistry instance which I need to pass in? I can't find any way to create an alias ID for it, or how to get it's ID or name.

+7  A: 

Maybe it's not a full answer to your questions, but maybe it might help you.

The code being called when you do NOT use programmatic login, but a standard one is to be found here:

org.springframework.security.ui.webapp.AuthenticationProcessingFilter

I guess you were inspired by this in your code. It looks quite similar.

Similarly the code executed when you access the /j_spring_security_logout in the standard approach, is to be found here:

org.springframework.security.ui.logout.LogoutFilter

The LogoutFilter calls multiple handlers. The handler we are using is called: org.springframework.security.ui.logout.SecurityContextLogoutHandler, so you might call the same code in your approach.

Grzegorz Oledzki
What a nice answer! :-)I was a bit more than inspired, by the Spring 3.0 reference documentation (the three lines in my try block are a straight copy-paste): http://static.springframework.org/spring-security/site/docs/3.0.x/reference/technical-overview.html#d4e689 .I should note though that I am using 2.0.4.I'll look into the code you mentioned! Thank you! I'm leaving the question open for now, as I'm still looking for some answers to my OP questions.
DeletedAccount
+3  A: 

Hey Kent,

You will indeed be open to session fixations attacks. To remedy this you could again be "inspired" by the spring code. To create a new session you'll obviously need access to the httpsession so you may have to do some refactoring.

If you see the startNewSessionIfRequired method on SessionUtils:

SessionUtils

This will migrate the authentication to a new session. You might be able to call this method directly or else just refactor the code a little.

As for programmatic logout you can't go too far wrong by simply calling session.invalidate() when you need to log the person out. This will do everything necessary from a general security perspective but bear in mind though you might need to cleanup some things on the session. If you have a very complicated set of filters etc. and you need to ensure that that the user is logged out for the rest of the request then you could add:

SecurityContextHolder.getContext().setAuthentication(null);

As for interception of the url's you could just set them to something unused and ignore it! I'm not sure if you can turn off the interception in configuration - if you really want to remove it then have a look at the AuthenticationProcessingFilter - you could customise this. If you do this then you'll have to manually setup the spring security xml and not use the provided namespaces. It's not too hard though - look at some older documentation and you'll see how to do this.

Hope this helps!

Pablojim
I created an update above as I'm having problems with the session fixation attack protection.
DeletedAccount
Have you a need to limit concurrent sessions? e.g. letting the same user login twice in two different sessions? If not you don't need a SessionRegistry - just pass a null value into the SessionUtils method.If you do need this then when you implement it you'll have a sessionRegistry! see here:http://static.springframework.org/spring-security/site/docs/2.0.x/reference/ns-config.html#ns-concurrent-sessionAgain for you you may need to configure it yourself and not use the custom namespace. My guess is you don't need this functionality.
Pablojim
SessionUtils was removed in spring-security 3.0, looks like org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy.onAuthentication() (and its subclass ConcurrentSessionControlStrategy) are its closest replacement.
Stefan L
+4  A: 

1) Programmatic Logout

  1. call HttpServletRequest.getSession(false).invalidate
  2. call SecurityContextHolder.clearContext()

2) Tell Spring Security NOT to intercept certain URLs, this one kind of depends on how your application url space is setup. If all your pages (except /logIn and /logout) lived at the context /myApp then you could do this:

<http ....>
  <intercept-url pattern="/myApp/**" ..>
 ....
</http>
Gandalf
A: 

To do programmatic logout it's also possible to throw an org.springframework.security.core.AuthenticationException. For example, SessionAuthenticationException. In this case ExceptionTranslationFilter initiate logout.

viator