【问题标题】:Variable Spring Security authentication-provider List变量 Spring Security 身份验证提供者列表
【发布时间】:2014-10-07 11:48:50
【问题描述】:

我想有条件地将身份验证提供程序添加到我的身份验证管理器中,但我无法弄清楚如何执行此操作。

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

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

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

谢谢

【问题讨论】:

  • 您可以将身份验证管理器部分放在单独的 xml 文件中,并根据配置文件在主 xml 文件的末尾导入。见stackoverflow.com/questions/16711760
  • @Ritesh ...但是如果有多个配置文件处于活动状态怎么办?然后不会尝试导入多个同名的bean吗?
  • 你是对的。它不支持多个配置文件。
  • 如果您可以更改每个提供程序的代码,那么您可以访问提供程序中的环境(使它们成为环境感知),如果支持的配置文件未激活,则从身份验证方法返回 null。

标签: java spring authentication spring-security


【解决方案1】:

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

我还没有测试解决方案。

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"/>

【讨论】:

    猜你喜欢
    • 2020-11-09
    • 2012-02-18
    • 2012-01-15
    • 1970-01-01
    • 2014-05-09
    • 1970-01-01
    • 2016-04-22
    • 1970-01-01
    • 2019-07-16
    相关资源
    最近更新 更多