问题
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.
回答1:
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.
回答2:
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 method SessionUtils.startNewSessionIfRequired
.
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!
回答3:
1) Programmatic Logout
- call HttpServletRequest.getSession(false).invalidate
- 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>
回答4:
I had an issue with programmatic login. I called all the authenticationManager.authenticate(...)
and SecurityContextHolder.getContext().setAuthentication(...)
methods but had some issues with the Session. I had to add the following lines to properly manage the session:
HttpSession session = request.getSession();
session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());
This was not clear from the example code posted above. For more look at http://forum.springsource.org/showthread.php?t=69761
回答5:
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.
回答6:
You can try this
try {
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
SecurityContextHolder.clearContext();
} catch (Exception e) {
logger.log(LogLevel.INFO, "Problem logging out.");
}
来源:https://stackoverflow.com/questions/1013032/programmatic-use-of-spring-security