创建委托身份验证提供程序(Spring Security)

Posted

技术标签:

【中文标题】创建委托身份验证提供程序(Spring Security)【英文标题】:Creating a delegating authentication provider (Spring Security) 【发布时间】:2019-07-16 15:21:12 【问题描述】:

我正在尝试创建一个委托身份验证提供程序来执行逻辑,然后再根据一些任意逻辑决定选择哪个身份验证提供程序;在本例中,如果用户名以前缀开头。

我当前的 SecurityConfig 将一次尝试一个身份验证提供程序:

public class SecurityConfig extends WebSecurityConfigurerAdapter 

    private final MyCustomCredentialAuthProvider myAuthProvider;

    ...

    @Override
    protected void configure(AuthenticationManagerBuilder auth) 
        auth
          .ldapAuthentication().configuration(...).here(...).etc(...).and() // ldapAuthenticationProvider is created here
          .authenticationProvider(myAuthProvider).and()
          // more authentication providers to be added in the future
    


根据用户名,我想选择是否要使用 try 提供程序,因此如果用户名不以特定前缀开头(“ldap”、“custom”、 "ad", "etc"...), 所以:

@Component
public class DelegatingProvider implements AuthenticationProvider 

    // Problem: How do I create this ldapAuthenticationProvider bean?
    private final LdapAuthenticationProvider ldapAuthenticationProvider;
    private final MyCustomCredentialAuthProvider myAuthProvider;

    ...

    @Override
    public Authentication authenticate(final Authentication authentication) throws AuthenticationException 
        if (authentication.getName() == null) 
            throw new BadCredentialsException("No username provided");
         else if (authentication.getName().startsWith("ldapPlease") 
           return ldapAuthProvider.authenticate(authentication);
        //  else if (...)  ...
        //  else if (...)  ...
         else  
           return myAuthProvider.authenticate(authentication);
        
    

    @Override
    public boolean supports(final Class<?> authentication) 
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);;
    


我似乎无法以这种方式连接 LdapProvider,因为它是由 SecurityConfig 创建的 - 当 LdapProvider bean 之前由 SecurityConfig 中的 AuthBuilder 处理时,我该如何创建和连接它?

【问题讨论】:

问题,如果你只是要使用 bean 为什么不直接@Autowired 呢? @Jose Luis 我正在努力解决如何实例化 spring 提供的 LdapAuthenticationProvider - 每个构建器和构造器似乎都是私有的,构建器模式似乎严重依赖于 AuthenticationBuilder。 如果您找到任何实例化 LdapAuthenticationProvider 的方法,请告诉我? @learner 恐怕我没有,我从来没有找到解决这个问题的方法 @TobiasRoland 我只是使用反射来做到这一点。在没有xml文件的情况下没有找到其他解决方案。 【参考方案1】:
    @Bean
    public LdapAuthenticationProvider ldapAuthentication() 
        return new LdapAuthenticationProviderConfigurer().configure(...).here(...).etc(...).build();
    
    .....................................
    @Component
    public class DelegatingProvider implements AuthenticationProvider 

        @Autowired
        private LdapAuthenticationProvider ldapAuthenticationProvider;

        @Autowired
        private final MyCustomCredentialAuthProvider myAuthProvider;

        ...

        @Override
        public Authentication authenticate(final Authentication authentication) throws AuthenticationException 
            if (authentication.getName() == null) 
                throw new BadCredentialsException("No username provided");
             else if (authentication.getName().startsWith("ldapPlease") 
               return ldapAuthProvider.authenticate(authentication);
            //  else if (...)  ...
            //  else if (...)  ...
             else  
               return myAuthProvider.authenticate(authentication);
            
        

        @Override
        public boolean supports(final Class<?> authentication) 
            return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);;
        
    

正如@NatFar 指定的那样

    @Autowired
    private DelegatingProvider delegatingProviderBean;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) 
        auth
          .authenticationProvider(delegatingProviderBean).and()
          // more authentication providers to be added in the future
    

【讨论】:

确保只在 configure(AuthenticationManagerBuilder auth) 中添加 delegatingProvider @Isey 你如何从 new LdapAuthenticationProviderConfigurer().builderMethods() 转到 AuthenticationProvider 的实际实例? @TobiasRoland LdapAuthenticationProviderConfigurer#build() 方法创建 LdapAuthenticationProvider。 哦,原来是私有方法。你可以尝试通过反射来调用它。 任何实例化 LdapAuthenticationProvider 对象的解决方案?

以上是关于创建委托身份验证提供程序(Spring Security)的主要内容,如果未能解决你的问题,请参考以下文章

spring security 无法添加自定义身份验证提供程序

具有 Spring Security 和 Java 配置的自定义身份验证管理器

Spring - 安全性:登录用户名和密码如何绑定到身份验证提供程序?

无法为 Spring Security 提供自定义身份验证提供程序

防止 Spring Security 通过下一个身份验证提供程序对具有 BadCredentialException 的用户进行身份验证

Asp.net 委托