可变Spring安全认证提供者列表



我想有条件地将身份验证提供程序添加到我的身份验证管理器,并且我很难弄清楚如何这样做。

假设定义了以下身份验证管理器:

<security:authentication-manager id="myAuthenticationManager" erase-credentials="true">
    <security:authentication-provider ref='ldapAuthenticationProvider'/>
    <security:authentication-provider ref='adLdapAuthenticationProvider'/>
    <security:authentication-provider user-service-ref='dbAthenticationService'>
        <security:password-encoder ref="myPasswordDigest">
            <security:salt-source ref="saltSource"/>
        </security:password-encoder>
    </security:authentication-provider>
</security:authentication-manager>

就像这样,Spring Security正在运行;我可以根据LDAP、Active Directory或我的数据库进行身份验证。我还可以选择删除其中一个提供程序,而程序仍然可以正常运行,所以这一切都很好。

但是,我希望通过使用Spring配置文件,可以动态地填充身份验证提供者列表。例如,在我的应用程序上下文的末尾,我有

<beans profile="db">
   <!-- Somehow add the following to myAuthenticationManager
    <security:authentication-provider user-service-ref='dbAthenticationService'>
        <security:password-encoder ref="myPasswordDigest">
            <security:salt-source ref="saltSource"/>
        </security:password-encoder>
    </security:authentication-provider> -->
</beans>
<beans profile="ldap">
    <!-- Somehow add the following to myAuthenticationManager
    <security:authentication-provider ref='ldapAuthenticationProvider'/> -->
</beans>
<beans profile="ad">
    <!-- Somehow add the following to myAuthenticationManager
    <security:authentication-provider ref='adLdapAuthenticationProvider'/> -->
</beans>

我已经有了配置文件切换机制,并且每个提供程序都被正确地单独配置了。我只想动态地填充初始化时要使用的列表。这可能吗?

谢谢

一个解决方案是注册一个身份验证提供者。此提供程序(见下文)引用所有身份验证提供程序并转发给正确的提供程序。

我还没有测试这个解决方案。

public class CompositeAuthenticationProvider implements AuthenticationProvider {
    private final List<AuthenticationProvider> providers = new ArrayList<>();
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        final AuthenticationProvider provider = getAuthenticationProvider(authentication.getClass());
        if(provider == null){
            throw new ProviderNotFoundException("The authentication [" +authentication
                  + "] is not supported by any provider");
        }
        return null;
    }
    @Override
    public boolean supports(final Class<?> authentication) {
        return getAuthenticationProvider(authentication) != null;
    }
    private AuthenticationProvider getAuthenticationProvider(Class<?> authentication) {
        for (AuthenticationProvider provider : providers) {
            if (provider.supports(authentication)) {
                return provider;
            }
        }
        return null;
    }
    @Autowired
    public void setProviders(List<AuthenticationProvider> providers) {
        this.providers.addAll(providers); // you could order them with @Order, just use a sorter
    }
}

XML定义:

<bean id="compositeAuthenticationProvider"
      class="CompositeAuthenticationProvider" autowire-candidate="false"/>

最新更新