填充sessionRegistry和会话控制

时间:2016-05-25 21:35:19

标签: spring security model-view-controller

大家晚上好。 我试图建立一个简单的MVC站点,而不使用xml配置,只使用java代码。 该网站有公共和私人内容,并通过春季安全管理。 我不想写饼干所以我写了

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
    @Override
    protected Set<SessionTrackingMode> getSessionTrackingModes() {
        return EnumSet.of(SessionTrackingMode.SSL);
    }
}

当我配置MVC时,我定义了bean

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.csbab.spring")
public class SpringWebConfiguration extends WebMvcConfigurerAdapter {

    @Bean(name = "sessionRegistry")
    public SessionRegistry sessionRegistry() {
      return new SessionRegistryImpl();
    }

    @Bean(name = "httpSessionEventPublisher")
    public HttpSessionEventPublisher httpSessionEventPublisher() {
        return new HttpSessionEventPublisher();
    }

在安全类中我有

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {


    @Autowired
    @Qualifier("customUserDetailsService")
    UserDetailsService userDetailsService;

    @Autowired
    private SessionRegistry sessionRegistry;

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    ...
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry authorizeRequests = http.authorizeRequests();

        authorizeRequests.and()
          .sessionManagement()
            .maximumSessions(1) // How many session the same user can have? This can be any number you pick
            .maxSessionsPreventsLogin(true)
            .expiredUrl("/login?expired")
            .sessionRegistry(sessionRegistry);
    ...

当用户登录此代码时调用

Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);

如果我尝试访问

@Autowired
private SessionRegistry sessionRegistry;

始终为空(即使用户已登录且ssl会话似乎处于活动状态)并且会话数量的安全检查失败...

有什么建议吗?

感谢。

继续(没人在回复......) 我添加了

@Bean(name = "sessionAuthenticationStrategy")
public SessionAuthenticationStrategy sessionAuthenticationStrategy(){
    List<SessionAuthenticationStrategy> delegateStrategies=new ArrayList<SessionAuthenticationStrategy>();
    ConcurrentSessionControlAuthenticationStrategy concurrent = new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry);
    concurrent.setMaximumSessions(1);
    concurrent.setExceptionIfMaximumExceeded(true);
    delegateStrategies.add(concurrent);
    delegateStrategies.add(new SessionFixationProtectionStrategy());
    delegateStrategies.add(new RegisterSessionAuthenticationStrategy(sessionRegistry));
    return new CompositeSessionAuthenticationStrategy(delegateStrategies);
} 

我删除了

authorizeRequests.and()           .sessionManagement()...

我将登录代码更改为

            SecurityContextHolder.getContext().setAuthentication(authentication);
            sessionAuthenticationStrategy.onAuthentication(authentication, request, response);
            return determineTargetUrl(authentication);
会话已经启动了sessionRegistry :)我做了第一个正面测试开放资源管理器和chrome(第二次登录被拒绝)

但是当我尝试从chrome(或其他chrome实例)中的新窗口登录时,我能够进行两次cuncurrent登录(共享相同的会话),并且我在日志中有此消息:

创建新会话时,您的servlet容器未更改会话ID。您将无法充分保护免受会话固定攻击

任何想法?

nosce te ipsum ...它只是代码...... 为了在我的场景中做我想做的事(可能不常见)我必须做一些不同的事情...... 阅读代码我意识到我对会话固定并不感兴趣,我希望每个用户只有一个会话,如果要求另一个会话,则出现安全问题或错误......所以我写了......

@Bean(name = "sessionAuthenticationStrategy")
public SessionAuthenticationStrategy sessionAuthenticationStrategy(){
    List<SessionAuthenticationStrategy> delegateStrategies=new ArrayList<SessionAuthenticationStrategy>();
    ConcurrentSessionControlAuthenticationStrategy concurrent = new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry);
    concurrent.setMaximumSessions(1);
    concurrent.setExceptionIfMaximumExceeded(true);
    delegateStrategies.add(concurrent);
    delegateStrategies.add(new SessionSingleUseProtectionStrategy(sessionRegistry));
    delegateStrategies.add(new RegisterSessionAuthenticationStrategy(sessionRegistry));
    return new CompositeSessionAuthenticationStrategy(delegateStrategies);
} 

我只能说这句话:)

1 个答案:

答案 0 :(得分:-1)

实例化

时sessionRegistry实例来自何处
new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry)

确保这与sessionRegistry()返回的实例相同(请注意多次调用该方法将创建多个实例!)

另外,我没有看到sessionAuthenticationStrategy绑定到会话管理的任何代码:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.sessionManagement().sessionAuthenticationStrategy(sessionAuthenticationStrategy());
}