Spring Security多重登录过滤器

时间:2017-01-05 01:15:06

标签: java spring spring-boot spring-security

我的Spring Boot应用程序中有两个不同的登录流程。

  1. 普通表格登录
  2. 无状态登录
  3. 我尝试了以下内容,但它始终是第二个过滤器。如何将/api/**限制为无状态身份验证,将其他人限制为正常会话表单登录?

    @Configuration
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        DataSource dataSource;
    
        @Autowired
        public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
            auth
                .jdbcAuthentication()
                    .dataSource(dataSource)
                    .usersByUsernameQuery("select username,password, enabled from users where username=?")
                    .authoritiesByUsernameQuery("select username, authority from authorities where username=?");
        } 
    
        private final UserService userService;
    
        private final TokenAuthenticationService tokenAuthenticationService;
    
        public WebSecurityConfig() {
             super(true);
             this.userService = new UserService();
             tokenAuthenticationService = new TokenAuthenticationService("tooManySecrets", userService);
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
             http
                 .csrf().disable();
    
             // Normal form login using jdbc
             http
                 .authorizeRequests()
                     .antMatchers("/", "/home").access("hasRole('ROLE_ADMIN')")
                     .and()
                 .formLogin()
                     .loginPage("/login")
                     .usernameParameter("username")
                     .passwordParameter("password")
                     .permitAll()
                     .and()
                 .logout().permitAll();
             //Stateless authentication using tokens - Custome authentication from token implemented in the filter
             http
                 .authorizeRequests()
                     .antMatchers("/api").authenticated()
                     .and()
                 .addFilterBefore(new StatelessAuthenticationFilter(tokenAuthenticationService),
                 UsernamePasswordAuthenticationFilter.class);
        }
    }
    

1 个答案:

答案 0 :(得分:0)

总的来说,Spring安全性通过使用多个HTTP块来处理这个问题。

您需要嵌套多个配置 - 这就是Java配置处理此问题的方式。重要的是,这些配置需要" Order"注释以确保spring以正确的顺序加载它们 - 必须在包含" /"的配置之前加载特定子路径(例如API)的配置。

所以你的例子会变成类似的东西(更多的重新排列可以使它更简单,只是展示分裂):

@Configuration
public class WebSecurityConfig {

    @Autowired
    private DataSource dataSource;

    private final UserService userService;

    private final TokenAuthenticationService tokenAuthenticationService;

    public WebSecurityConfig() {
        super(true);
        this.userService = new UserService();
        tokenAuthenticationService = new TokenAuthenticationService("tooManySecrets", userService);
    }

    @Order(0)
    @Configuration
    private final class ApiSecurity extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
           http.csrf().disable();

            //Stateless authentication using tokens - Custome authentication from token implemented in the filter
            http.antMatchers("/api").authorizeRequests()
               .authenticated().and()
               .addFilterBefore(new StatelessAuthenticationFilter(tokenAuthenticationService),
             UsernamePasswordAuthenticationFilter.class);
        }

        @Autowired
        public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
          auth.jdbcAuthentication().dataSource(dataSource)
             .usersByUsernameQuery("select username,password, enabled from users where username=?")
             .authoritiesByUsernameQuery("select username, authority from authorities where username=?");
    } 
    }

     @Order(Ordered.LOWEST_PRECEDENCE)
     @Configuration
     private final class OtherSecurity extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
           http.csrf().disable();

            //Normal form login using jdbc
            http.antMatchers("/", "/home").authorizeRequests().access("hasRole('ROLE_ADMIN')").and().formLogin()
               .loginPage("/login") .usernameParameter("username")
               .passwordParameter("password").permitAll().and().logout().permitAll();
        }

        @Autowired
        public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
          auth.jdbcAuthentication().dataSource(dataSource)
             .usersByUsernameQuery("select username,password, enabled from users where username=?")
             .authoritiesByUsernameQuery("select username, authority from authorities where username=?");
        } 
    }
}