简体   繁体   English

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

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

How can I switch security model in runtime so that 如何在运行时切换安全模型,以便

  1. an existing spring security component can produce an Authentication , and 现有的spring安全组件可以产生Authentication ,并且
  2. an existing spring security component can validate the Authentication 现有的spring安全组件可以验证Authentication

I think I resolved (2) but cannot quite figure out (1) . 我认为我已经解决了(2),但不能完全弄清(1)


Spring Security configuration 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();
    }
}

The SwitchingAuthenticationProvider is straight forward: simply delegate to some other AuthenticationProvder (ie, LDAP/OAUTH2 or otherwise) SwitchingAuthenticationProvider很简单:只需委托给其他一些AuthenticationProvder (即LDAP / OAUTH2或其他)

(inspired by Switching authentication approaches at runtime with Spring Security ). (受Spring Security在运行时切换身份验证方法的启发)。

public class SwitchingAuthenticationProvider implements AuthenticationProvider {

    private AuthenticationProvider[] authProviders = // ...

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

But what creates the Authentication ? 但是,什么创建了Authentication As I understand it one option is to let the GenericFilterBean create the Authentication as illustrated below. 据我了解,一种选择是让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);
   }
}

... where an AuthProviderService would delegate to something that creates an authentication . ... AuthProviderService将委托给创建authentication But how can I plug it with eg, the equivalent of HttpSecurity#httpBasic() or HttpSecurity#openIdLogin() ? 但是如何将其插入等效的HttpSecurity#httpBasic()HttpSecurity#openIdLogin()呢?


Bonus question: What's the difference between HttpSecurity#authenticationProvider(..) and AuthenticationManagerBuilder.authenticationProvider(..) ? 额外的问题: HttpSecurity#authenticationProvider(..)AuthenticationManagerBuilder.authenticationProvider(..)之间有什么区别?

It appears the Filter is responsible to create the Authentication (not sure if anything else is too). 它出现的Filter 负责创建Authentication (不知道别的太)。

The AnonymousAuthenticationFilter as an example AnonymousAuthenticationFilter为例

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

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

Similar I think the SwitchingFilter should be similar to SwitchingAuthenticationProvider 类似,我认为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); ??
   }
}

.. for some mechanism of selecting a suitable index i . ..用于选择合适索引i某种机制。

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

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