大家晚上好。 我试图建立一个简单的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);
}
我只能说这句话:)
答案 0 :(得分:-1)
实例化
时sessionRegistry实例来自何处new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry)
确保这与sessionRegistry()返回的实例相同(请注意多次调用该方法将创建多个实例!)
另外,我没有看到sessionAuthenticationStrategy绑定到会话管理的任何代码:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionAuthenticationStrategy(sessionAuthenticationStrategy());
}