首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring安全-多配置-添加LogoutHandler

Spring安全-多配置-添加LogoutHandler
EN

Stack Overflow用户
提问于 2017-11-02 07:02:11
回答 3查看 1.9K关注 0票数 14

我有一个使用spring-security的spring-boot应用程序。安全配置分为多个WebSecurityConfigurerAdapter实例。

我有一个配置注销的地方:

代码语言:javascript
复制
@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
}

还有另一个WebSecurityConfigurerAdapter,除了添加另一个LogoutHandler,我几乎什么都不想做:

代码语言:javascript
复制
@Override
protected void configure(HttpSecurity http) throws Exception {

    // configure logout
    http
            .logout()
            .logoutUrl("/logout")
            .addLogoutHandler((request, response, authentication) -> {
                System.out.println("logged out 2!");
            });
}

这两个configure()方法都被调用。但是,如果我真的注销了,只会调用第一个LogoutHandler。更改两种配置的@Order不会更改结果。

我的配置中缺少什么?

EN

回答 3

Stack Overflow用户

发布于 2017-11-13 15:54:18

当您创建多个安全配置时,Spring Boot将为每个配置创建一个单独的SecurityFilterChain。请参阅WebSecurity

代码语言:javascript
复制
@Override
protected Filter performBuild() throws Exception {
    // ...
    for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) {
        securityFilterChains.add(securityFilterChainBuilder.build());
    }
    // ...
}

当应用程序收到注销请求时,FilterChainProxy将只返回一个SecurityFilterChain:

代码语言:javascript
复制
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;
}

如果你真的需要模块化的安全配置,我建议你为注销和其他领域创建一个单独的安全配置。您可以在不同的配置类中将注销处理程序定义为beans (使用@Bean注释),并在注销配置中收集这些处理程序:

WebSecurityLogoutConfiguration.java

代码语言:javascript
复制
@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
    }
}

WebSecurity1Configuration.java

代码语言:javascript
复制
@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!");
        };
    }
}

WebSecurity2Configuration.java

代码语言:javascript
复制
@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!");
        };
    }
}
票数 8
EN

Stack Overflow用户

发布于 2017-11-10 16:09:18

您应该在您的单个/logout操作端点上使用CompositeLogoutHandler解决此问题。

您仍然可以根据需要保留两个WebSecurityConfigurerAdapter,但您将把两个LogoutHandler的注销功能聚合到一个复合操作中:

代码语言:javascript
复制
new CompositeLogoutHandler(loggedOutHandler1, loggedOutHandler2);
票数 0
EN

Stack Overflow用户

发布于 2017-11-13 12:43:32

关键点是您应该创建独立的AuthenticationManger实例。

Here is an sample for multiples WebSecurityAdapter

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47064993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档