使用具有不同AuthenticationProviders的多个WebSecurityConfigurerAdapter(用于Web应用程序的API和LDAP的基本身份验证) [英] Using multiple WebSecurityConfigurerAdapter with different AuthenticationProviders (basic auth for API and LDAP for web app)

查看:193
本文介绍了使用具有不同AuthenticationProviders的多个WebSecurityConfigurerAdapter(用于Web应用程序的API和LDAP的基本身份验证)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 Spring Security Reference section 5.7 应该可以定义多个安全适配器。

According the Spring Security Reference section 5.7 it should be possible to define more than one security adapter.

我尝试做同样但没有成功。在服务器重新启动之后,API的前x次正常使用基本身份验证,但是经过几次我被重定向到登录(表单)页面,这应该只针对我们的Web应用程序,而不是API调用。

I try to do the same but without success. After a server reboot, the first x times the API works fine with basic auth, but after a couple of times I'm redirected to the login (form) page, this should only happen for our web app, not for the API calls.

我的代码:

@EnableWebSecurity
public class MultiHttpSecurityConfig  {

    @Configuration
    @Order(1)
    public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {

        @Autowired
        private Environment env;

        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication().
                withUser("admin").password("pw_test").roles(API_ROLE);
        }

        protected void configure(HttpSecurity http) throws Exception {
            http
              .antMatcher("/services/**")
              .authorizeRequests()
              .anyRequest().hasRole(API_ROLE)
              .and()
              .httpBasic()
              .and()
              .csrf()
              .disable();
        }
    }

    @Configuration
    @Order(2)
    public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Autowired
        private Environment env;

        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
            auth.eraseCredentials(false);
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // LDAP FORM AUTHENTICATION
            http.authorizeRequests()
                .antMatchers("/login.html").permitAll()
                .antMatchers("/css/**").permitAll() 
                .antMatchers("/js/**").permitAll() 
                .antMatchers("/images/**").permitAll() 
                .anyRequest().authenticated()
            .and().formLogin()
                .failureUrl("/login.html?error=1")
                .loginPage("/login.html")
                .loginProcessingUrl("/j_spring_security_check")
                .defaultSuccessUrl("/success.html")
                .usernameParameter("j_username")
                .passwordParameter("j_password")
                .permitAll();

            http.csrf().disable();

            // iFRAMES SETTINGS
            http
                .headers()
                .frameOptions().sameOrigin()
                .httpStrictTransportSecurity().disable();

            // HTTPS
            http
                .requiresChannel()
                .anyRequest()
                .requiresSecure();

            //MAP 8080 to HTTPS PORT
            http.portMapper().http(8080).mapsTo(443);
        }

        @Bean
        public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
            CustomLdapAuthenticationProvider provider = new CustomLdapAuthenticationProvider(env.getProperty("ldap.domain"), env.getProperty("ldap.url"), env.getProperty("ldap.base"));
            provider.setConvertSubErrorCodesToExceptions(true);
            provider.setUseAuthenticationRequestCredentials(true);
            return provider;
        }
    }
}

有什么想法吗?

我正在使用Spring Boot版本1.4.1-RELEASE和Spring Security版本4.1.3-RELEASE。

I'm using Spring Boot version 1.4.1-RELEASE and Spring Security version 4.1.3-RELEASE.

推荐答案

你使用相同的 AuthenticationManager ,因为您自动装配相同的 AuthenticationManagerBuilder

You use the same AuthenticationManager for both configurations, because you autowire the same AuthenticationManagerBuilder.

请参阅 Spring Security Architecture


@Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {

    ... // web stuff here

    @Autowired
    public initialize(AuthenticationManagerBuilder builder, DataSource dataSource) {
        auth.jdbcAuthentication().dataSource(dataSource).withUser("dave")
            .password("secret").roles("USER");
    }

}

此示例与Web应用程序有关,但 AuthenticationManagerBuilder 的使用更为广泛适用(有关如何实施Web应用程序安全性的更多详细信息,请参阅下文)。请注意, AuthenticationManagerBuilder @Autowired @Bean - 这就是它构建全局(父)AuthenticationManager的原因。相反,如果我们这样做:

This example relates to a web application, but the usage of AuthenticationManagerBuilder is more widely applicable (see below for more detail on how web application security is implemented). Note that the AuthenticationManagerBuilder is @Autowired into a method in a @Bean - that is what makes it build the global (parent) AuthenticationManager. In contrast if we had done it this way:

@Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {

    @Autowired
    DataSource dataSource;

    ... // web stuff here

    @Override
    public configure(AuthenticationManagerBuilder builder) {
        auth.jdbcAuthentication().dataSource(dataSource).withUser("dave")
            .password("secret").roles("USER");
    }

}

(使用配置器中方法的@Override 然后 AuthenticationManagerBuilder 仅用于构建本地 AuthenticationManager ,这是全球的孩子。

(using an @Override of a method in the configurer) then the AuthenticationManagerBuilder is only used to build a "local" AuthenticationManager, which is a child of the global one.

这篇关于使用具有不同AuthenticationProviders的多个WebSecurityConfigurerAdapter(用于Web应用程序的API和LDAP的基本身份验证)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆