Spring Boot安全性 - 多个身份验证提供者

4

我的问题是我想要有两个认证提供者。

之前: 我有我的UserDetailServiceImpl并且对用户进行了验证,根据数据库中的数据分配角色,不确定这是什么提供程序。

现在: 我已经使用了ActiveDirectoryLdapAuthentication提供程序,如下所示:

  @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        super.configure(auth);
        auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider()).userDetailsService(userDetailService);
    }

    @Bean
    public AuthenticationManager authenticationManager() {
        return new ProviderManager(Arrays.asList(activeDirectoryLdapAuthenticationProvider()));
    }
    @Bean
    public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
       MyActiveDirectoryLdapAuthenticationProvider provider = new MyActiveDirectoryLdapAuthenticationProvider(domain, url, rootDN);
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);

        return provider;
    }

我已经使它工作了,所以我能够进行身份验证。

问题:

  1. 我现在无法再使用数据库用户登录,只能使用LDAP。
  2. UserDetailsService没有被使用,那么用户有哪些角色?
  3. 有没有办法为LDAP认证的用户添加一些默认角色?

如何同时启用两个提供者? 如何为通过LDAP auth.provider进行身份验证的用户添加角色?

我也很想知道这里发生了什么(底层)的“大局观”描述。每个使用的类扮演什么角色,这真的不清楚它是如何工作的(AuthenticationManager、AuthenticationManagerBuilder、AuthenticationProvider等)。也许它只是被自动配置隐藏了,但即使直接查看Spring Security也不能让我更聪明。

感谢任何提示

更新 此代码似乎正常工作

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider()).userDetailsService(userDetailService);
    }

    public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
        MyActiveDirectoryLdapAuthenticationProvider provider = new MyActiveDirectoryLdapAuthenticationProvider(domain, url, rootDN);
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);
        provider.setAuthoritiesMapper(new SimpleAuthorityMapper());
        return provider;
    }
1个回答

1

问题太多了!

由于您将两个提供程序都添加到AuthenticationManagerBuilder中,因此两个提供程序都已启用。但是,您将它们都添加到同一过滤器链中,并且两者都接受相同类型的Authentication作为输入,因此其中一个始终会掩盖另一个。

标准的LdapAuthenticationProvider具有一个authoritiesMapper,您可以使用它将权限从目录条目映射到用户(通常使用目录组来完成,例如请参见sample)。我想,如果您的目录不包含组,则可以使用自定义映射器使所有用户具有相同的权限或其他一些内容。

您的@Beans类型为AuthenticationManagerAuthenticationProvider看起来非常冗余(并且可能是有害的,因为它们是全局的,并且您正在为单个过滤器链配置AuthenticationManagerBuilder)。我怀疑您根本不需要那个AuthenticationManager方法,而另一个方法不需要是公共的或@Bean(可能不需要)。


这是否意味着我不能同时对两个提供者进行身份验证?在数据库中拥有超级用户,如果LDAP宕机也能够登录等。AuthoritiesMapper可能会有所帮助,我们在AD中可能也有一些组,我会检查一下。明天尝试您的建议。暂时谢谢。 - Zveratko
没有 @Bean public AuthenticationManager authenticationManager(),它完全停止工作了 :-/ - Zveratko
有几个AuthenticationManagerBuilders被创建了,我认为应该只有一个。我不明白。 - Zveratko
一个应用程序中可以很容易地有许多AuthenticationManagers。它们以不同的方式和在不同的代码路径中使用。您正在配置的是由您提供的WebSecurityConfigurer创建的过滤器链的本地AuthenticationManager - Dave Syer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接