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

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

问题描述

根据 Spring 安全参考第 5.7 节 应该可以定义多个安全适配器.

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

我的代码:

@EnableWebSecurity公共类 MultiHttpSecurityConfig {@配置@订单(1)公共静态类 ApiWebSecurityConfigurationAdapter 扩展了 WebSecurityConfigurerAdapter {@自动连线私人环境环境;@自动连线public void configureGlobal(AuthenticationManagerBuilder auth) 抛出异常 {auth.inMemoryAuthentication().withUser("admin").password("pw_test").roles(API_ROLE);}protected void configure(HttpSecurity http) 抛出异常 {http.antMatcher("/services/**").authorizeRequests().anyRequest().hasRole(API_ROLE).和().httpBasic().和().csrf().disable();}}@配置@订单(2)公共静态类 FormLoginWebSecurityConfigurerAdapter 扩展 WebSecurityConfigurerAdapter {@自动连线私人环境环境;@自动连线public void configureGlobal(AuthenticationManagerBuilder auth) 抛出异常 {auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());auth.eraseCredentials(false);}@覆盖protected void configure(HttpSecurity http) 抛出异常 {//LDAP 表单认证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 设置http.headers().frameOptions().sameOrigin().httpStrictTransportSecurity().disable();//HTTPShttp.requiresChannel().anyRequest().requiresSecure();//将8080映射到HTTPS端口http.portMapper().http(8080).mapsTo(443);}@豆角,扁豆公共 AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {CustomLdapAuthenticationProvider provider = new CustomLdapAuthenticationProvider(env.getProperty("ldap.domain"), env.getProperty("ldap.url"), env.getProperty("ldap.base"));provider.setConvertSubErrorCodesToExceptions(true);provider.setUseAuthenticationRequestCredentials(true);返回提供者;}}}

有什么想法吗?

我使用的是 Spring Boot 版本 1.4.1-RELEASE 和 Spring Security 版本 4.1.3-RELEASE.

解决方案

你用同样的 AuthenticationManager 用于两种配置,因为您自动装配相同的 AuthenticationManagerBuilder.

参见 Spring 安全架构:

<块引用>

@Configuration公共类 ApplicationSecurity 扩展了 WebSecurityConfigurerAdapter {...//这里的网络内容@自动连线公共无效初始化(AuthenticationManagerBuilder 构建器,数据源数据源){builder.jdbcAuthentication().dataSource(dataSource).withUser("dave").password("secret").roles("USER");}}

此示例与 Web 应用程序相关,但 AuthenticationManagerBuilder 的用法适用范围更广(有关如何实现 Web 应用程序安全性的更多详细信息,请参见下文).请注意,AuthenticationManagerBuilder@Autowired@Bean 中的一个方法 - 这就是它构建全局(父)AuthenticationManager 的原因.相反,如果我们这样做:

@Configuration公共类 ApplicationSecurity 扩展了 WebSecurityConfigurerAdapter {@自动连线数据源数据源;...//这里的网络内容@覆盖公共无效配置(AuthenticationManagerBuilder 构建器){builder.jdbcAuthentication().dataSource(dataSource).withUser("dave").password("secret").roles("USER");}}

(在配置器中使用一个方法的 @Override)那么 AuthenticationManagerBuilder 仅用于构建本地"AuthenticationManager,这是全局的孩子.

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

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.

My code:

@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;
        }
    }
}

Any idea?

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

解决方案

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

See Spring Security Architecture:

@Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {

    ... // web stuff here

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

}

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 void configure(AuthenticationManagerBuilder builder) {
        builder.jdbcAuthentication().dataSource(dataSource).withUser("dave")
            .password("secret").roles("USER");
    }

}

(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(API 的基本身份验证和 Web 应用程序的 LDAP)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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