繁体   English   中英

如何使用Spring Security在运行时切换安全模型?

[英]How to switch security model in runtime with spring security?

如何在运行时切换安全模型,以便

  1. 现有的spring安全组件可以产生Authentication ,并且
  2. 现有的spring安全组件可以验证Authentication

我认为我已经解决了(2),但不能完全弄清(1)


Spring Security配置

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/**").authenticated().and()
            .addFilterBefore(switchingFilter);
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(switchingAuthenticationProvider);
    }

    @Bean
    public SwitchingAuthenticationProvider switchingAuthenticationProvider() {
        return new SwitchingAuthenticationProvider();
    }

    @Bean
    public SwitchingFilter switchingFilter() {
        return new SwitchingFilter();
    }
}

SwitchingAuthenticationProvider很简单:只需委托给其他一些AuthenticationProvder (即LDAP / OAUTH2或其他)

(受Spring Security在运行时切换身份验证方法的启发)。

public class SwitchingAuthenticationProvider implements AuthenticationProvider {

    private AuthenticationProvider[] authProviders = // ...

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        return authProvider[i].authenticate(authentication);
    }
}

但是,什么创建了Authentication 据我了解,一种选择是让GenericFilterBean创建Authentication ,如下所示。

public class SwitchingFilter extends GenericFilterBean {

    private AuthProviderService authProviders = // ...

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        Authentication authentication = authProviders.getAuthentication(request);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        filterChain.doFilter(request, response);
        SecurityContextHolder.getContext().setAuthentication(null);
   }
}

... AuthProviderService将委托给创建authentication 但是如何将其插入等效的HttpSecurity#httpBasic()HttpSecurity#openIdLogin()呢?


额外的问题: HttpSecurity#authenticationProvider(..)AuthenticationManagerBuilder.authenticationProvider(..)之间有什么区别?

它出现的Filter 负责创建Authentication (不知道别的太)。

AnonymousAuthenticationFilter为例

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
        throws IOException, ServletException {

    if (SecurityContextHolder.getContext().getAuthentication() == null) {
        SecurityContextHolder.getContext().setAuthentication(
                createAuthentication((HttpServletRequest) req));
}

类似,我认为SwitchingFilter应该类似于SwitchingAuthenticationProvider

public class SwitchingFilter extends GenericFilterBean {

    private Filter[] filters = // ...

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        filters[i].doFilter(request, response, chain);
        // do filterChain.doFilter(request, response); ??
   }
}

..用于选择合适索引i某种机制。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM