1

我有spring security的示例用例:

<sec:http auto-config="true" xmlns="http://www.springframework.org/schema/security">
    <intercept-url pattern="/secure/**" access="ROLE_USER" />
    <intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
    <sec:anonymous username="lolka"/>
</sec:http>

<sec:authentication-manager xmlns="http://www.springframework.org/schema/security">
    <authentication-provider>
        <user-service>
            <user name="admin" password="adminpassword" authorities="ROLE_USER, ROLE_ADMIN" />
            <user name="user" password="userpassword" authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>
</sec:authentication-manager>

在这个示例配置中,创建AnonymousAuthenticationFilter了处理匿名用户并使用我的主体名称向他们提供的配置:lolka. 此过滤器的生成发生在AuthenticationConfigBuilder.createAnonymousFilter. 如果打开该方法的代码,我们还可以发现,还创建了分配给的 AnonymousAuthenticationProvider anonymousProviderRef,因此这个 authenticationProvader应该存在于我的身份验证提供者列表中,但是如果我在运行时获取身份验证提供者列表,则有only DaoAuthenticationProvider,它是从sec:authentication-manager标签创建的。

我有在运行时获取身份验证提供程序的代码:@Autowired private ApplicationContext applicationContext;

@PostConstruct
public void init(){
    Object bean = applicationContext.getBean("authenticationManager");
    log.info("authenticationManager:{}",bean);
    ProviderManager vefified = (ProviderManager) bean;
    log.info("providers:{}",vefified.getProviders());


    try {
        Field ff = vefified.getClass().getDeclaredField("parent"); 
        ff.setAccessible(true);
        Object parentObj = ff.get(vefified);
        if(ProviderManager.class.isInstance(parentObj)){
            log.info("parent is instance of ProviderManager:{}", parentObj.getClass().getSimpleName());
            ProviderManager verifyedParent = (ProviderManager)parentObj;
            log.info("parent providers list:{}", verifyedParent.getProviders());
        } else {
            log.info("parent is NOT instance of ProviderManager:{}", parentObj);
        }
    } catch (Throwable e) {
        e.printStackTrace();
    }

    AnonymousAuthenticationProvider anonProvider = applicationContext.getBean(AnonymousAuthenticationProvider.class);
    log.info("AnonymousAuthenticationProvider:{}",anonProvider);

}

并且有输出:

INFO (Main.java:35) authenticationManager:org.springframework.security.authentication.ProviderManager@1566060
INFO (Main.java:37) providers:[org.springframework.security.authentication.dao.DaoAuthenticationProvider@1d1695e]
INFO (Main.java:49) parent is NOT instance of ProviderManager:null
INFO (Main.java:56) AnonymousAuthenticationProvider:org.springframework.security.authentication.AnonymousAuthenticationProvider@187d27e

所以我的问题是:

  1. 如果使用 AnonymousAuthenticationProvider,它的目的是什么?
  2. 为什么 AnonymousAuthenticationProvider 存在于运行时,但不存在于 List 中authenticationManager

Spring 版本为:3.2.4.RELEASE Spring 安全版本为:3.1.4.RELEASE

4

1 回答 1

2

实际上ProviderManager,为您创建的每个过滤器链创建了另一个内部实例,<http>并且匿名提供程序就在其中。“父”AuthenticationManager是您使用命名空间声明的那个,它包含“真正的”身份验证提供程序。

AnonymousAuthenticationProvider并没有真正做任何有用的事情。我只是将其视为主要的设计遗产,而不是您需要担心的事情。如果它不存在,则不会处理此令牌类型,并且AuthenticationManager会引发ProviderNotFoundException.

于 2013-10-30T23:17:58.080 回答