spring - 针对不同的 url 模式使用不同的过滤器

标签 spring spring-security spring-boot

我有一个 Spring Boot 应用程序,主要提供 REST 端点,身份验证是通过 token (在 Authorization header 中发送)完成的,我在 之前添加了自己的 TokenAuthenticationFilter >LogoutFilter 设置安全上下文。

在创建管理控制台的过程中,我希望管理员身份验证与普通用户分开,因为我不会在管理员用户之间共享多个表原因,在数据库级别我有以下user,user_token,admin,admin_token。所以为了完成这个,我想了几个解决方案:

  1. 让当前的TokenAuthenticationFilter处理用户/管理员 token 授权。然而,这将需要: 将过滤器修改为 根据 url 模式确定是管理员 token 还是用户 token (例如,如果它是 /admin/**,过滤器就会知道哪个 调用的服务)具有与用户不同的管理员 header (即用户发送 U-Auth header ,管理员发送 A-Auth header )并且过滤器将根据 header 名称进行操作。这一切 我觉得不太好。
  2. 指定一组过滤器以应用于每个网址模式,例如 /admin/** 会将 AdminTokenAuthFilter 添加到链中, 而任何其他模式都会有旧的 链中的TokenAuthenticationFilter。这听起来比 早期的方法,但我在实现它时遇到了麻烦。我试过 在我的 WebSecurityConfigurerAdapter
  3. 中注册我自己的 FilterRegistrationBean

示例:

 @Bean
 public FilterRegistrationBean adminFilter(){
     FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
     filterRegBean.setFilter(new AdminTokenAuthFilter());
     List<String> urlPatterns = new ArrayList<>();
     urlPatterns.add("/admin/*");
     filterRegBean.setUrlPatterns(urlPatterns);
     return filterRegBean;
 }

这似乎有效,但我不确定这是否是正确的做法,我还担心一件事,我发现这将过滤器添加到过滤器的 springs originalChain 中,而不是添加到 additionalFilters 似乎适用于使用 http.addFilterBefore(tokenAuthenticationFilter, LogoutFilter.class) 在我的 WebSecurityConfigurerAdapter 中定期添加过滤器。我不想改变 Spring 原始过滤器链,我宁愿在附加过滤器链中添加自定义过滤器。谁能详细说明一下吗?

  • 创建两个单独的调度程序 servlet 并让每个都监听 特定的 url 模式,我想每个 dispatcherServlet 将有自己的安全配置。
  • 任何人都可以分享一些有关这种情况下最佳方法的知识吗?

    最佳答案

    最终编写了两个安全配置,第一个适用于特定的 antmatcher,第二个适用于任何其他 url 模式。就像这样:

    @Configuration
    @EnableWebSecurity
    @ComponentScan(basePackages = "x.x.x")
    public class NewSecurityConfiguration {
        @Configuration
        @Order(1)
        public static class BackendSecurityConfiguration extends WebSecurityConfigurerAdapter {
            @Autowired CustomSystemUserDetailsService customSystemUserDetailsService;
            @Autowired SystemTokenAuthFilter systemTokenAuthFilter;
            @Autowired CustomLogoutFilter customLogoutFilter;
            @Autowired UnauthorizedEntryPoint unauthorizedEntryPoint;
    
            @Bean
            public PasswordEncoder passwordEncoder() {
                return new BCryptPasswordEncoder();
            }
    
            @Bean(name="systemAuthenticationManager")
            @Override
            public AuthenticationManager authenticationManagerBean() throws Exception {
                return super.authenticationManagerBean();
            }
    
            @Override
            public void configure(AuthenticationManagerBuilder auth) throws Exception {                
                auth.userDetailsService(customSystemUserDetailsService).passwordEncoder(passwordEncoder());
            }
    
            @Override
            protected void configure(HttpSecurity http) throws Exception {    
                http.antMatcher("/system/**")
                        .addFilterBefore(systemTokenAuthFilter, LogoutFilter.class)
                        .addFilterBefore(customLogoutFilter, LogoutFilter.class)
                        .authorizeRequests()
                        .antMatchers("/system/login").permitAll()
                        .anyRequest().authenticated()
                        .and()
                        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                        .and()
                        .exceptionHandling().authenticationEntryPoint(unauthorizedEntryPoint)
                        .and()
                        .httpBasic().disable()
                        .csrf().disable()
                        .logout().disable();
            }
        }
    
        @Configuration
        @Order(2)
        public static class FrontEndSecurityConfiguration extends WebSecurityConfigurerAdapter {
    
            @Override
            public void configure(AuthenticationManagerBuilder auth) throws Exception {
                auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
            }
    
            @Override
            protected void configure(HttpSecurity http) throws Exception {
                http
                        .addFilterBefore(userTokenAuthFilter, LogoutFilter.class)
                        .addFilterBefore(customLogoutFilter, LogoutFilter.class)
                        .authorizeRequests()
                        .antMatchers("/access/*").permitAll()
                        .antMatchers("/ref/*").permitAll()
                        .antMatchers("/ticket_parser/*").permitAll()
                        .antMatchers("/reset_password/**").permitAll()
                        .antMatchers("/link_profile/**").permitAll()
                        .antMatchers("/email_verification/**").permitAll()
                        .antMatchers("/ref").permitAll()
                        .antMatchers("/flightstats/alert").permitAll()
                        .antMatchers("/airline/list").access("authenticated or hasIpAddress('127.0.0.1') or hasIpAddress('0:0:0:0:0:0:0:1')")
                        .antMatchers("/airport/list").access("authenticated or hasIpAddress('127.0.0.1') or hasIpAddress('0:0:0:0:0:0:0:1')")
                        .and()
                        .authorizeRequests().anyRequest().authenticated().and().authorizeRequests()
                        .and()
                        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                        .and()
                        .exceptionHandling().authenticationEntryPoint(unauthorizedEntryPoint)
                        .and()
                        .httpBasic().disable()
                        .csrf().disable()
                        .formLogin().disable()
                        .logout().disable();
            }
        }
    }
    

    关于spring - 针对不同的 url 模式使用不同的过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36066720/

    相关文章:

    java - 如何修复 native 查询 : it is showing syntax error near or at 中的错误

    java - 如何更新Spring Jpa中的对象?

    grails - SpringSecurity重播登录Grails

    spring-boot - 使用 OAuth2 身份验证启用 Spring Boot Health Actuator

    json - Spring 中的非必需 JSON 属性(Jackson 映射)

    java - Spring构造函数注入(inject)有很多字段

    java - ClassNotFoundException : org. springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerConfiguration

    java - Mysql 和 Spring Boot

    spring-boot - 可执行Spring Boot 2 jar

    java - 使用映射实体映射对象