Open anschnapp opened 7 years ago
Hi, I have done some further investigation on the issue.
I have tried to make a fix for the SessionManagementFilter so it will work even if there is a security context with empty authentication.
But on testing my fix things seems different.
For authentication I use a UsernamePasswordAuthenticationFilter which inherits from AbstractAuthenticationProcessingFilter. This filter will not call the other filter chain if it's authenticate successful. So the SessionManagementFilter is not invoked for the call where the authentication succeed. Of course the SecurityContextPersistenceFilter will save the security context after the authentication (inside the finally block).
So the session authentication strategy (potential session fixation protection) inside of SessionManagementFilter will never be invoked (even with my "fixed" version).
I have seen that the AbstractAuthenticationProcessingFilter have the possibility to make a session authentication strategy on it's own. But this is deactivate by default. I have set the session fixation protection strategy inside of the AbstractAuthenticationProcessingFilter, and now it works.
But I would recommend to not close this ticket yet (even if my personal problem is solved now)
In the documentation I have read that the SessionManagementFilter should handle such things like session invalidation. But as I already described this don't seem to work. So for me it looks like it's likely that this failure is not only related to me.
And if it would work why is there an additional possibility to configure it on AbstractAuthenticationProcessingFilter level? Isn't this a redundancy of which filter is responsible for such a security concern? IMHO there should be only one filter which is concerned for session auth strategy and this filter should be configured for a session fixation protection strategy.
In javadoc of SessionManagementFilter
;
* Detects that a user has been authenticated since the start of the request and, if they
* have, calls the configured {@link SessionAuthenticationStrategy} to perform any
* session-related activity such as activating session-fixation protection mechanisms or
* checking for multiple concurrent logins.
However as @git2snap stated, a successful authentication does not end up calling SessionManagementFilter
since AbstractAuthenticationProcessingFilter prevents executing remaining filters in security filter chain.
What would be the correct setup for using session concurrency management?
我也遇到相同的问题,SessionManagementFilter
中的 sessionAuthenticationStrategy
不起作用。配置控制并发认证(登录)的代码也不能起作用,如下代码
http.sessionManagement()
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
.sessionRegistry(sessionRegistry)
AbstractAuthenticationProcessingFilter
类重写successfulAuthentication
方法 @Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult)
throws IOException, ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult);
}
SecurityContextHolder.getContext().setAuthentication(authResult);
this.getRememberMeServices().loginSuccess(request, response, authResult);
// Fire event
if (this.eventPublisher != null) {
eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
}
chain.doFilter(request, response); // 调用过滤器链
this.getSuccessHandler().onAuthenticationSuccess(request, response, authResult);
}
手动调用 chain.doFilter(request, response);
解决问题
This just took me 2 hours of debugging :/
Having same issue, when UsernamePasswordAuthenticationFilter is used SessionManagementFilter never calls sessionAuthenticationStrategy.onAuthentication because securityContextRepository.containsContext(request) is never false
I have the same issue described by @jukkasi with the default configuration in Spring Boot and
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
}
}
The sequence of events is:
Authorization: Basic XXX
=> Set-Cookie: JSESSIONID=ABC
Authorization: Basic YYY
and Cookie: JSESSIONID=ABC
=> no Set-Cookie
header returned.Cookie: JSESSIONID=ABC
and without Authorization
=> session ABC
is now associated with the principal of "user2".My understanding is that this is a textbook example of a session fixation attack which is very worrisome.
As mentioned above, the decision point for this behavior is SessionManagementFilter#doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
where if (!securityContextRepository.containsContext(request))
is never false
I also tried with this configuration which made no difference (because of SessionManagementFilter
) :
http.sessionManagement().sessionFixation().newSession()
Summary
Session authentication strategy is not called after a successfully authentication.
I have used the standard strategy against session fixation, but this is not called.
Actual Behavior
This issue appears if:
As a result: Session authentication strategy is not called after successfully authentication.
Expected Behavior
Session authentication strategy is called after successfully authentication.
Configuration
I have configured spring security with the default filter chain (normal order)
Special to mention for the described error: I use the org.springframework.security.web.context.SecurityContextPersistenceFilter as the first filter in the chain. I have used the standard SessionManagementFilter (which is configured with SessionFixationProtectionStrategy).
Version
4.2.1 RELEASE
Details of the cause
I have debugged the behavior and I think I have found the root cause.
After the filter chain was proceeded the SecurityContextPersistenceFilter invoke a saveContext on the configured SecurityContextRepository. (this happens every time and is located in a finally block). As you can see here:
The standard implementation of the repository is the HttpSessionSecurityContextRepository. This one saves a given security context to the session. In this case this is a SecurityContext with an null authentication inside. (will be result from repo.loadContext(holder) if there is no context yet).
This happens on each normal requests. (it seems that this mechanism don't make a session for itself but the state is saved is there was a given session in the request)
So if there was some normal requests there is an empty (not null) security context in the session.
And if this is the case the logic of SessionManagementFilter will not work properly. The configured session authentication strategy will only invoke if the following if statement is true:
This function just checks if there is something in the session and is not null
But there is an empty not null security context in the session and so the logic inside the if will not be executed and no session invalidation will be invoked.