Java Config SecurityBuilder的顺序';s
我正在使用SpringSecurity4.0.0的Java配置而不是xml配置开发一个web应用程序。我正在使用Java Config SecurityBuilder的顺序';s,java,spring-security,Java,Spring Security,我正在使用SpringSecurity4.0.0的Java配置而不是xml配置开发一个web应用程序。我正在使用ObjectPostProcessors定制一些Spring Security的bean,特别是会话concurrency bean(在用户再次登录时立即使会话失效,而不是Spring在下一次请求时使会话失效的标准行为) 它在大多数情况下都能按预期工作,但有时当我重新启动应用程序时,似乎并不是所有的bean都能按照我的要求进行修改 SecurityBuilders是按特定顺序处理的,还
ObjectPostProcessor
s定制一些Spring Security的bean,特别是会话concurrency bean(在用户再次登录时立即使会话失效,而不是Spring在下一次请求时使会话失效的标准行为)
它在大多数情况下都能按预期工作,但有时当我重新启动应用程序时,似乎并不是所有的bean都能按照我的要求进行修改
SecurityBuilder
s是按特定顺序处理的,还是按ramdom顺序处理的
编辑:
我的配置
@EnableWebSecurity
公共类SecurityConfig扩展了AbstractCasWebSecurity配置适配器{
公共安全配置(){
超级(真、假、真);
}
@自动连线
私人环境署;
//我们需要一个自定义的SessionRegistry,因为无法获得由配置程序创建的SessionRegistry。
@豆子
公共会话注册表会话注册表(){
返回新的SessionRegistryImpl();
}
//我们需要一个定制的HttpSessionsRftokenRepository,因为无法获得由配置程序创建的HttpSessionsRftokenRepository。
@豆子
公共CsrfTokenRepository CsrfTokenRepository(){
返回新的httpsessionsrftokenrepository();
}
//我们的自定义ConcurrentSessionControlAuthenticationStrategy立即使会话无效
@豆子
公共会话验证ConcurrentSessionControlAuthenticationStrategy myConcurrentSessionControlAuthenticationListener()
{
//我们必须重新创建LogoutHandler,因为我们需要调用它们
//在使会话无效之前
最终LogoutHandler[]LogoutHandler=新LogoutHandler[]{
新CookieClearningLogoutHandler(“JSSessionID”),
新的CsrfLogoutHandler(csrfTokenRepository())
//,new SecurityContextLogoutHandler()//重定向到导致登录请求的同一页面时似乎会产生问题
};
SessionInvalidating ConcurrentSessionControlAuthenticationStrategy mine=新SessionInvalidating ConcurrentSessionControlAuthenticationStrategy(sessionRegistry(),LogoutHandler);
mine.setExceptionIfmaximumExcepended(false);
矿山。设置最大会话(1);
回采;
}
@凌驾
public void configure(WebSecurity web)引发异常{
super.configure(web);
布尔devMode=this.env.acceptsProfiles(“开发”);
最终字符串[]ignoredPaths=devMode
?新字符串[]{/webjars/**“,”/static/**“,“/bower_components/**”}
:新字符串[]{“/webjars/**”,“/static/**”};
网状物
.忽略()
.蚂蚁匹配器(忽略路径)
.及()
.debug(false)
;
}
受保护的void configure(最终HttpSecurity http)引发异常{
super.configure(http);
http
.会议管理()
.maximumSessions(73467436)//这只是为了触发ConcurrencyControlConfigurer
.sessionRegistry(sessionRegistry())
.及()
.withObjectPostProcessor(新的ObjectPostProcessor(){
@抑制警告(“未选中”)
@凌驾
公共O后处理(O ConcurrentSessionControl){
//替换由创建的ConcurrentSessionControlAuthenticationStrategy
//我们自己的并发控制配置程序
返回(O)myConcurrentSessionControlAuthenticationListener();
}
})
.及()
//我们需要忽略stomp端点,以允许SockJS javascript客户端发出POST请求
//使用非WebSocket的trasports时,按/推/。/../;
//此时,Stomp CSRF头提供保护
.csrf()
.csrfTokenRepository(csrfTokenRepository())
.ignoringAntMatchers(“/push/**”)
.及()
//允许同一来源构建我们的站点以支持iframe SockJS
.headers()
.frameOptions().sameOrigin()
.及()
.授权请求()
.antMatchers(“/help/**”).permitAll()//帮助重定向不需要身份验证
.antMatchers(“/push/info”).permitAll()//不要求SockJS对/info请求进行身份验证
.anyRequest().authenticated()
.及()
//注销时删除会话cookie
.logout()
.deleteCookies(“JSESSIONID”)//请参阅:http://docs.spring.io/autorepo/docs/spring-security/current/reference/htmlsingle/#detecting-超时
.及()
;
}
}
AbstractCasWebSecurityConfigureAdapter
是一个配置CAS的AbstractWebSecurityConfigureAdapter。您能提供您的配置和ObjectPostProcessor吗?@RobWinch添加了我的对话。
@EnableWebSecurity
public class SecurityConfig extends AbstractCASWebSecurityConfigurerAdapter {
public SecurityConfig() {
super(true, false, true);
}
@Autowired
private Environment env;
// we need a custom SessionRegistry as there's no way to get ahold of the one created by the configurer.
@Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
// we need a custom HttpSessionCsrfTokenRepository as there's no way to get ahold of the one created by the configurer.
@Bean
public CsrfTokenRepository csrfTokenRepository() {
return new HttpSessionCsrfTokenRepository();
}
// our custom ConcurrentSessionControlAuthenticationStrategy that invalidates session immediately
@Bean
public SessionInvalidatingConcurrentSessionControlAuthenticationStrategy myConcurrentSessionControlAuthenticationListener()
{
// we have to recreate the LogoutHandlers because we need to call them
// before invalidating the session
final LogoutHandler [] logoutHandlers = new LogoutHandler [] {
new CookieClearingLogoutHandler("JSESSIONID"),
new CsrfLogoutHandler(csrfTokenRepository())
//, new SecurityContextLogoutHandler() // seems to create problems with redirecting to the same page that caused the login request
};
SessionInvalidatingConcurrentSessionControlAuthenticationStrategy mine = new SessionInvalidatingConcurrentSessionControlAuthenticationStrategy(sessionRegistry(), logoutHandlers);
mine.setExceptionIfMaximumExceeded(false);
mine.setMaximumSessions(1);
return mine;
}
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
boolean devMode = this.env.acceptsProfiles("development");
final String [] ignoredPaths = devMode
? new String [] {"/webjars/**", "/static/**", "/bower_components/**" }
: new String [] {"/webjars/**", "/static/**" };
web
.ignoring()
.antMatchers(ignoredPaths)
.and()
.debug(false)
;
}
protected void configure(final HttpSecurity http) throws Exception {
super.configure(http);
http
.sessionManagement()
.maximumSessions(73467436) // this is just to trigger the ConcurrencyControlConfigurer
.sessionRegistry(sessionRegistry())
.and()
.withObjectPostProcessor(new ObjectPostProcessor<ConcurrentSessionControlAuthenticationStrategy>() {
@SuppressWarnings("unchecked")
@Override
public <O extends ConcurrentSessionControlAuthenticationStrategy> O postProcess(O concurrentSessionControlAS) {
// substitute the ConcurrentSessionControlAuthenticationStrategy created by
// ConcurrencyControlConfigurer with our own
return (O) myConcurrentSessionControlAuthenticationListener();
}
})
.and()
// we need to ignore the stomp endpoint to allow SockJS javascript client to issue POST requests
// to /push/../../.. when using trasports which are not WebSocket;
// at that time, protection is given by Stomp CSRF headers
.csrf()
.csrfTokenRepository(csrfTokenRepository())
.ignoringAntMatchers("/push/**")
.and()
// allow same origin to frame our site to support iframe SockJS
.headers()
.frameOptions().sameOrigin()
.and()
.authorizeRequests()
.antMatchers("/help/**").permitAll() // help redirects do not require authentication
.antMatchers("/push/info").permitAll() // do not require being authenticated for the /info request by SockJS
.anyRequest().authenticated()
.and()
// remove the session cookie when logging out
.logout()
.deleteCookies("JSESSIONID") // see: http://docs.spring.io/autorepo/docs/spring-security/current/reference/htmlsingle/#detecting-timeouts
.and()
;
}
}