如何配置Spring Web应用程序以在每个端点使用不同的身份验证方法

时间:2018-05-10 04:29:25

标签: java spring spring-mvc spring-security

我有一个使用Java,Spring和Spring Security构建的Web应用程序 - 需要支持两种不同的身份验证方法。我遇到的困难是我想在一组控制器端点上使用一种身份验证方法,在剩余的端点上使用另一种方法。

这是一个难题,因为我读过的有关多个身份验证提供程序的所有文档似乎都假设您希望所有提供程序都应用于所有端点,并且您遍历提供程序,直到找到将对其进行身份验证的提供程序。用户。

我正在使用基于Java注释的配置(而不是XML配置)。以下是我探索过的一些没有成功的方法:

  • 使用模式匹配器配置提供程序以限制其应用的端点
  • 将提供程序配置为仅针对某些身份验证类型触发,例如。如果存在摘要凭据,则触发基于摘要的身份验证提供程序

有谁能建议最好的方法是什么?以上方法之一是正确的方法(我只是错了)?或者还有另一种首选方式吗?

(我知道我没有提供具体的代码来审查问题。这是因为我只是在关于在Spring工作的适当方式的指导之后。)

1 个答案:

答案 0 :(得分:1)

我正在使用Spring Boot 2.0。我不知道最好的方法,但这是一种适合我的方式。我不得不将其分解为单独的配置类和第二个配置,以便在其上添加 @Order 注释。

对于我的特定情况,我需要一些由HTTP基本身份验证(用户名/密码)保护的管理REST方法,其余的REST方法需要通过自定义逻辑进行保护。

@Configuration
@EnableWebSecurity
public class TestSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().permitAll();

        // anything that is NOT /admin/**
        RequestMatcher requestMatcher = new NegatedRequestMatcher(new AntPathRequestMatcher("/admin/**", "GET"));

        // MyCustomFilter is my class that performs custom authentication logic
        http.requestMatcher(requestMatcher)
            .addFilterAfter(new MyCustomFilter(), BasicAuthenticationFilter.class);
    }


    @Order(1)
    @Configuration
    public static class AdminServiceConfiguration extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            //this time anything that IS /admin/**
            http.requestMatchers()
                .antMatchers("/admin/**").and()
                .httpBasic().and()
                .authorizeRequests().antMatchers("/admin/**").fullyAuthenticated();
        }

        @Override
        protected void configure(AuthenticationManagerBuilder authBuilder) throws Exception {
            authBuilder.inMemoryAuthentication()
                .passwordEncoder(NoOpPasswordEncoder.getInstance())
                .withUser("username")
                .password("password")
                .roles("ADMIN");
        }
    }
}