1

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

  1. 一个现有的 spring 安全组件可以产生一个Authentication, 和
  2. 现有的 spring 安全组件可以验证Authentication

我想我解决了(2)但不能完全弄清楚(1)


弹簧安全配置

@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);
   }
}

...其中 anAuthProviderService将委托给创建 authentication. 但是我怎样才能将它插入例如,相当于HttpSecurity#httpBasic()or HttpSecurity#openIdLogin()


HttpSecurity#authenticationProvider(..)奖金问题:和有什么区别AuthenticationManagerBuilder.authenticationProvider(..)

4

1 回答 1

1

似乎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

于 2016-03-02T10:43:12.100 回答