Rüd*_*ulz 14 java security spring spring-mvc spring-security
我有一个使用spring-security的spring-boot应用程序.安全配置分为多个实例WebSecurityConfigurerAdapter
.
我有一个配置注销的一般方法:
@Override
protected void configure(HttpSecurity http) throws Exception {
// configure logout
http
.logout()
.logoutUrl("/logout")
.invalidateHttpSession(true)
.addLogoutHandler((request, response, authentication) -> {
System.out.println("logged out 1!");
})
.permitAll();
// ... more security configuration, e.g. login, CSRF, rememberme
}
Run Code Online (Sandbox Code Playgroud)
WebSecurityConfigurerAdapter
除了添加另一个LogoutHandler之外,还有另外一个我几乎什么都不想做的事情:
@Override
protected void configure(HttpSecurity http) throws Exception {
// configure logout
http
.logout()
.logoutUrl("/logout")
.addLogoutHandler((request, response, authentication) -> {
System.out.println("logged out 2!");
});
}
Run Code Online (Sandbox Code Playgroud)
两种configure()
方法都被调用.但是,如果我注销,则仅LogoutHandler
调用第一个.更改@Order
两种配置不会改变结果.
我的配置中缺少什么?
小智 7
当您创建多个安全配置时,Spring Boot将为每个配置创建一个单独的SecurityFilterChain.请参阅WebSecurity:
@Override
protected Filter performBuild() throws Exception {
// ...
for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) {
securityFilterChains.add(securityFilterChainBuilder.build());
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
当应用程序获得注销请求时,FilterChainProxy将只返回一个SecurityFilterChain:
private List<Filter> getFilters(HttpServletRequest request) {
for (SecurityFilterChain chain : filterChains) {
// Only the first chain that matches logout request will be used:
if (chain.matches(request)) {
return chain.getFilters();
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
如果您确实需要模块化安全配置,我建议为注销和其他领域创建单独的安全配置.您可以@Bean
在不同的配置类中将注销处理程序定义为bean(使用注释),并在注销配置中收集这些处理程序:
WebSecurityLogoutConfiguration.java
@Configuration
@Order(99)
public class WebSecurityLogoutConfiguration extends WebSecurityConfigurerAdapter {
// ALL YOUR LOGOUT HANDLERS WILL BE IN THIS LIST
@Autowired
private List<LogoutHandler> logoutHandlers;
@Override
protected void configure(HttpSecurity http) throws Exception {
// configure only logout
http
.logout()
.logoutUrl("/logout")
.invalidateHttpSession(true)
// USE CompositeLogoutHandler
.addLogoutHandler(new CompositeLogoutHandler(logoutHandlers));
http.csrf().disable(); // for demo purposes
}
}
Run Code Online (Sandbox Code Playgroud)
WebSecurity1Configuration.java
@Configuration
@Order(101)
public class WebSecurity1Configuration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// ... more security configuration, e.g. login, CSRF, rememberme
http.authorizeRequests()
.antMatchers("/secured/**")
.authenticated();
}
// LOGOUT HANDLER 1
@Bean
public LogoutHandler logoutHandler1() {
return (request, response, authentication) -> {
System.out.println("logged out 1!");
};
}
}
Run Code Online (Sandbox Code Playgroud)
WebSecurity2Configuration.java
@Configuration
@Order(102)
public class WebSecurity2Configuration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/api/**")
.permitAll();
}
// LOGOUT HANDLER 2
@Bean
public LogoutHandler logoutHandler2() {
return (request, response, authentication) -> {
System.out.println("logged out 2!");
};
}
}
Run Code Online (Sandbox Code Playgroud)
您应该在单个操作端点上使用CompositeLogoutHandler/logout
来解决此问题。
您仍然可以根据需要保留两个WebSecurityConfigurerAdapter,但是您会将两个的注销功能合并LogoutHandler
到一个复合操作中:
new CompositeLogoutHandler(loggedOutHandler1, loggedOutHandler2);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1097 次 |
最近记录: |