Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用AuthenticationManagerBuilder的提供程序订单_Java_Spring_Authentication_Spring Security - Fatal编程技术网

Java 使用AuthenticationManagerBuilder的提供程序订单

Java 使用AuthenticationManagerBuilder的提供程序订单,java,spring,authentication,spring-security,Java,Spring,Authentication,Spring Security,我正在使用SpringSecurity4.0.1,并希望使用多个身份验证提供程序来使用基于Java的配置进行身份验证。如何指定提供程序顺序 我希望使用,因为这是websecurityConfigureAdapter.configureGlobal()公开的内容,但我看不到任何指定顺序的方法。我是否需要手动创建一个文件 更新:根据阿伦的回答,这里有一个问题澄清。我要使用的特定提供程序是自定义用户服务的ActiveDirectoryLdapAuthenticationProvider和DAAuthe

我正在使用SpringSecurity4.0.1,并希望使用多个身份验证提供程序来使用基于Java的配置进行身份验证。如何指定提供程序顺序

我希望使用,因为这是
websecurityConfigureAdapter.configureGlobal()
公开的内容,但我看不到任何指定顺序的方法。我是否需要手动创建一个文件

更新:根据阿伦的回答,这里有一个问题澄清。我要使用的特定提供程序是自定义
用户服务的
ActiveDirectoryLdapAuthenticationProvider
DAAuthenticationProvider

最后,我想首先对
DaoAuthenticationProvider
进行身份验证,然后对
activedirectoryldapaauthenticationprovider
进行身份验证

AD提供程序涉及调用
AuthenticationManagerBuilder.authenticationProvider()
,但DAO提供程序涉及调用
AuthenticationManagerBuilder.userService()
,这将在后台用户服务周围创建一个
DAOAAuthenticationProvider
。看看源代码,它没有直接将提供者放在提供者列表中(它创建了一个配置器),因此Arun的答案在这里对我不起作用


我尝试手动创建
DaoAuthenticationProvider
,并将其传递给
authenticationProvider()
。它没有影响订单。

没有明确的订购规定。调用顺序将是您向
AuthenticationManagerBuilder.AuthenticationProvider()提供
AuthenticationProvider
的顺序。请参阅xml配置。这同样适用于java配置

例如

auth.authenticationProvider(getAuthenticationProvider2());
auth.authenticationProvider(getAuthenticationProvider1());
将导致以下调用顺序
AuthenticationProvider2,AuthenticationProvider1


将导致以下调用顺序
AuthenticationProvider1,AuthenticationProvider2

我在configure方法中尝试了objectPostProcessor,它成功了。不确定这是否是您想要的:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      auth.jdbcAuthentication().dataSource(dataSource)
           .passwordEncoder(new BCryptPasswordEncoder());
      auth.authenticationProvider(new CustomAuthenticationProvider(this.dataSource));

      auth.objectPostProcessor(new ObjectPostProcessor<Object>() {
        @Override
        public <O> O postProcess(O object) {
            ProviderManager providerManager = (ProviderManager) object;
            Collections.swap(providerManager.getProviders(), 0, 1);
            return object;
        }
    });
}
@覆盖
受保护的无效配置(AuthenticationManagerBuilder auth)引发异常{
auth.jdbccauthentication().dataSource(dataSource)
.passwordEncoder(新的BCryptPasswordEncoder());
auth.authenticationProvider(新的CustomAuthenticationProvider(this.dataSource));
auth.objectPostProcessor(新的objectPostProcessor(){
@凌驾
公共O后处理(O对象){
ProviderManager ProviderManager=(ProviderManager)对象;
swap(providerManager.getProviders(),0,1);
返回对象;
}
});
}
这是WebSecurity ConfigureAdapter继承类上的配置方法

使用对象后处理器的原因是,我们需要等待AuthenticationManagerBuilder实际构建对象,然后才能访问和更改提供者列表的顺序


希望能有帮助。。如果您有任何问题,请告诉我。

我在Spring 5应用程序中遇到了完全相同的问题,但在我的情况下,创建
DaoAuthenticationProvider
有帮助。这是我的代码(我省略了很多,粘贴了最重要的代码)


谢谢你,阿伦。我查看了代码,可以看出这对AuthenticationProviders是有效的,我们显式地通过authenticationProvider()方法,因此+1是有效的。但我正试图让它与用户服务一起工作。我会相应地更新问题。我可以看看您的spring安全配置代码吗?我想了解身份验证提供程序是如何配置的。当您使用
authenticationManagerBuilder.ldapaauthentication()
(当ldap位于最后一个位置,并且您不能强制它位于自定义身份验证提供程序之前)时,它可以工作,也可以应用它
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      auth.jdbcAuthentication().dataSource(dataSource)
           .passwordEncoder(new BCryptPasswordEncoder());
      auth.authenticationProvider(new CustomAuthenticationProvider(this.dataSource));

      auth.objectPostProcessor(new ObjectPostProcessor<Object>() {
        @Override
        public <O> O postProcess(O object) {
            ProviderManager providerManager = (ProviderManager) object;
            Collections.swap(providerManager.getProviders(), 0, 1);
            return object;
        }
    });
}
...
import javax.annotation.PostConstruct;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Import(SecurityProblemSupport.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);

    private final AuthenticationManagerBuilder authenticationManagerBuilder;

    private final UserDetailsService userDetailsService;

    private final TokenProvider tokenProvider;

    private final CorsFilter corsFilter;

    private final SecurityProblemSupport problemSupport;

    public SecurityConfiguration(AuthenticationManagerBuilder authenticationManagerBuilder, UserDetailsService userDetailsService, TokenProvider tokenProvider, CorsFilter corsFilter, SecurityProblemSupport problemSupport) {
        this.authenticationManagerBuilder = authenticationManagerBuilder;
        this.userDetailsService = userDetailsService;
        this.tokenProvider = tokenProvider;
        this.corsFilter = corsFilter;
        this.problemSupport = problemSupport;
    }

    @PostConstruct
    public void init() {
        try {
            authenticationManagerBuilder.authenticationProvider(userDetailsAuthenticationProvider());

            if (isSsoEnabled()) {
                authenticationManagerBuilder
                    .authenticationProvider(activeDirectoryLdapAuthenticationProvider());
            }

            if (isKerberosEnabled()) {
                authenticationManagerBuilder
                    .authenticationProvider(kerberosServiceAuthenticationProvider());
            }

        } catch (Exception e) {
            throw new BeanInitializationException("Security configuration failed", e);
        }
    }

    @Bean
    public DaoAuthenticationProvider userDetailsAuthenticationProvider() {
        DaoAuthenticationProvider authProvider
            = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService);
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new CustomPasswordEncoder();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        ...
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    ...
    }

    private JWTConfigurer securityConfigurerAdapter() {
        return new JWTConfigurer(tokenProvider);
    }

    private ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
        ActiveDirectoryLdapAuthenticationProvider provider =
            new ActiveDirectoryLdapAuthenticationProvider(getAdDomain(), getAdServer());
        provider.setUserDetailsContextMapper((UserDetailsContextMapper) userDetailsService);
        return provider;
    }


    private boolean isSsoEnabled() {
        return Boolean.parseBoolean(ConfigurationFileUtils.getConfigurationProperty("security.use-sso"));
    }

    private boolean isKerberosEnabled() {
        return isSsoEnabled() && Boolean.parseBoolean(ConfigurationFileUtils.getConfigurationProperty("security.use-kerberos"));
    }    
}