SpringSecurity定义多个过滤器链的操作代码

yizhihongxing

要定义多个过滤器链,需要使用Spring Security提供的WebSecurityConfigurerAdapter类,该类可以用于配置Spring Security的安全性过滤器链。

以下是定义多个过滤器链的完整攻略:

  1. 创建一个类继承WebSecurityConfigurerAdapter类,并覆盖configure(HttpSecurity http)方法。例如:

```java
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

   @Override
   protected void configure(HttpSecurity http) throws Exception {
       http.authorizeRequests()
               .antMatchers("/admin/**").hasRole("ADMIN")
               .antMatchers("/**").permitAll()
               .and().formLogin().loginPage("/login")
               .and().logout().logoutUrl("/logout").permitAll();
   }

}
```

在上面的例子中,我们定义了一个SecurityConfig类,它继承了WebSecurityConfigurerAdapter类。在这个类中,我们覆盖了configure(HttpSecurity http)方法来定义一些安全配置。具体来说,我们定义了两个安全过滤器链:
* /admin/**路径下的请求必须具有ROLE_ADMIN角色才能访问。
* 其他请求都允许访问,并设置了表单登录和退出登录功能。

注意,这里只定义了一个过滤器链。

  1. 创建一个新的配置类,它也必须继承WebSecurityConfigurerAdapter类,并覆盖configure(HttpSecurity http)方法。例如:

```java
@Configuration
@Order(1)
public class ApiSecurityConfig extends WebSecurityConfigurerAdapter {

   @Override
   protected void configure(HttpSecurity http) throws Exception {
       http.antMatcher("/api/**")
               .authorizeRequests().anyRequest().hasRole("API")
               .and().httpBasic().disable();
   }

}
```

在上面的例子中,我们定义了另一个配置类ApiSecurityConfig,它继承了WebSecurityConfigurerAdapter类,并使用@Order(1)注解指定了它的优先级。另外,我们使用了.antMatcher("/api/**")来匹配以/api/开头的路径,并且设置只有拥有ROLE_API角色的用户才能访问。

  1. 将定义好的配置类注册到Spring容器中。例如:

```java
@SpringBootApplication
public class DemoApplication {

   public static void main(String[] args) {
       SpringApplication.run(DemoApplication.class, args);
   }

   @Configuration
   @EnableWebSecurity
   public static class MultiHttpSecurityConfig {

       @Autowired
       private ApiSecurityConfig apiSecurityConfig;

       @Autowired
       private SecurityConfig securityConfig;

       @Bean(name = "apiSecurityFilter")
       public FilterSecurityInterceptor apiSecurityFilter() throws Exception {
           FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
           interceptor.setAuthenticationManager(authenticationManager());
           interceptor.setSecurityMetadataSource(securityMetadataSource());
           interceptor.setAccessDecisionManager(accessDecisionManager());
           return interceptor;
       }

       @Bean(name = "securityFilter")
       public FilterSecurityInterceptor securityFilter() throws Exception {
           FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
           interceptor.setAuthenticationManager(authenticationManager());
           interceptor.setSecurityMetadataSource(securityMetadataSource());
           interceptor.setAccessDecisionManager(accessDecisionManager());
           return interceptor;
       }

       @Bean
       public FilterRegistrationBean<FilterSecurityInterceptor> apiSecurityFilterRegistration(
               @Qualifier("apiSecurityFilter") FilterSecurityInterceptor filter) {
           FilterRegistrationBean<FilterSecurityInterceptor> registration = new FilterRegistrationBean<>(filter);
           registration.setOrder(1);
           registration.addUrlPatterns("/api/*");
           return registration;
       }

       @Bean
       public FilterRegistrationBean<FilterSecurityInterceptor> securityFilterRegistration(
               @Qualifier("securityFilter") FilterSecurityInterceptor filter) {
           FilterRegistrationBean<FilterSecurityInterceptor> registration = new FilterRegistrationBean<>(filter);
           registration.setOrder(2);
           registration.addUrlPatterns("/*");
           return registration;
       }

       @Bean
       public DefaultWebSecurityExpressionHandler securityExpressionHandler() {
           return new DefaultWebSecurityExpressionHandler();
       }

       @Bean
       public FilterInvocationSecurityMetadataSource securityMetadataSource() {
           return new DefaultFilterInvocationSecurityMetadataSource(
                   new LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>>() {{
                       put(new AntPathRequestMatcher("/admin/**"), SecurityConfig.createList("ROLE_ADMIN"));
                       put(new AntPathRequestMatcher("/api/**"), SecurityConfig.createList("ROLE_API"));
                       put(new AntPathRequestMatcher("/**"), SecurityConfig.createList("IS_AUTHENTICATED_ANONYMOUSLY"));
                   }});
       }

       @Bean
       public AccessDecisionManager accessDecisionManager() {
           return new AffirmativeBased(Collections.singletonList(new RoleVoter()));
       }

   }

}
```

在上面的例子中,我们在Spring Boot的主类DemoApplication中创建了一个静态内部类MultiHttpSecurityConfig。在该类中,我们获取之前定义好的两个配置类,并创建了两个过滤器实例。然后,我们将这两个实例通过FilterRegistrationBean注册到Spring容器中,并分别为它们指定了不同的URL模式和执行顺序。接着,我们定义了一些辅助类和方法,包括DefaultWebSecurityExpressionHandler、DefaultFilterInvocationSecurityMetadataSource、AccessDecisionManager等。最后,我们使用注解@EnableWebSecurity启用了Spring Security功能。

注意,我们还使用了@Order注解来指定ApiSecurityConfig类的执行顺序为1,而SecurityConfig类的执行顺序则默认为2。

这样,我们就定义了两个不同的过滤器链,一个处理所有路径,另一个只处理/api/路径下的请求。

下面是另一个示例,假设我们要定义一个过滤器链,只有满足特定条件的请求才会被认证:

@Configuration
@EnableWebSecurity
public class MultiHttpSecurityConfig {

    @Autowired
    private SpecialConditionFilter specialConditionFilter;

    @Bean(name = "specialConditionFilter")
    public FilterSecurityInterceptor specialConditionFilter() throws Exception {
        FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
        interceptor.setAuthenticationManager(authenticationManager());
        interceptor.setSecurityMetadataSource(securityMetadataSource());
        interceptor.setAccessDecisionManager(accessDecisionManager());
        return interceptor;
    }

    @Bean
    public FilterRegistrationBean<FilterSecurityInterceptor> specialConditionFilterRegistration(
            @Qualifier("specialConditionFilter") FilterSecurityInterceptor filter) {
        FilterRegistrationBean<FilterSecurityInterceptor> registration = new FilterRegistrationBean<>(filter);
        registration.setOrder(1);
        registration.addUrlPatterns("/*");
        return registration;
    }

    @Bean
    public DefaultWebSecurityExpressionHandler securityExpressionHandler() {
        return new DefaultWebSecurityExpressionHandler();
    }

    @Bean
    public FilterInvocationSecurityMetadataSource securityMetadataSource() {
        return new DefaultFilterInvocationSecurityMetadataSource(
                new LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>>() {{
                    put(new AntPathRequestMatcher("/admin/**"), SecurityConfig.createList("ROLE_ADMIN"));
                    put(new AntPathRequestMatcher("/**"), SecurityConfig.createList("IS_AUTHENTICATED_ANONYMOUSLY"));
                }});
    }

    @Bean
    public AccessDecisionManager accessDecisionManager() {
        return new AffirmativeBased(Collections.singletonList(new RoleVoter()));
    }

    @Bean
    public SpecialCondition specialCondition() {
        return new SpecialCondition();
    }

    @Bean
    public SpecialConditionEvaluationContextExtension specialConditionExtension() {
        return new SpecialConditionEvaluationContextExtension();
    }

    public static class SpecialConditionFilter extends AbstractAuthenticationProcessingFilter {

        protected SpecialConditionFilter() {
            super(new AntPathRequestMatcher("/*"));
        }

        @Override
        public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
                throws AuthenticationException, IOException, ServletException {
            SpecialCondition specialCondition = findSpecialCondition(request);
            if (specialCondition != null && specialCondition.getValue() == 123) {
                return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(
                        specialCondition, null, Collections.singletonList(new SimpleGrantedAuthority("SPECIAL"))));
            } else {
                return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(
                        null, null, Collections.singletonList(new SimpleGrantedAuthority("ANONYMOUS"))));
            }
        }

        private SpecialCondition findSpecialCondition(HttpServletRequest request) {
            // ...
        }

    }

    public static class SpecialConditionEvaluationContextExtension implements EvaluationContextExtension {

        @Override
        public String getExtensionId() {
            return "specialCondition";
        }

        @Override
        public ExtensionPropertyAccessors getPropertyAccessors() {
            return new ExtensionPropertyAccessors() {

                @Override
                public boolean canRead(EvaluationContext context, Object target, String name)
                        throws AccessException {
                    if (target instanceof SpecialCondition && "value".equals(name)) {
                        return true;
                    }
                    return false;
                }

                @Override
                public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
                    if (target instanceof SpecialCondition && "value".equals(name)) {
                        return new TypedValue(((SpecialCondition) target).getValue());
                    }
                    throw new NoSuchPropertyException(target.getClass(), name);
                }

                @Override
                public boolean canWrite(EvaluationContext context, Object target, String name)
                        throws AccessException {
                    return false;
                }

                @Override
                public void write(EvaluationContext context, Object target, String name, Object newValue)
                        throws AccessException {
                    throw new NoSuchPropertyException(target.getClass(), name);
                }

            };
        }

    }

    public static class SpecialCondition {

        public int getValue() {
            return 123;
        }

    }

}

在这个示例中,我们创建了一个名为SpecialCondition的Java类,它只有一个名为value的int类型属性,表示特定条件。然后,我们创建了一个SpecialConditionFilter类,它是AbstractAuthenticationProcessingFilter类的子类,用于处理所有路径。在这个过滤器中,我们查找请求中是否符合特定条件,并根据结果来选择不同的认证方式。最后,我们通过SpecialConditionEvaluationContextExtension扩展了表达式语言的功能,使其能够访问到SpecialCondition类中的value属性。此外,我们还定义了一些Spring Bean,并将它们注册到Spring容器中。

这就是定义多个过滤器链的完整攻略,其中包含两个不同的示例。这些示例有助于理解如何在Spring Security中定义和配置多个过滤器链。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringSecurity定义多个过滤器链的操作代码 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Java8中的LocalDateTime你会使用了吗

    当我们需要对日期和时间进行操作时,通常使用Java的Date或Calendar对象。但是Java 8 引入了新的时间API,其中包括LocalDateTime类,可以更方便地处理日期和时间。 LocalDateTime的基本用法 LocalDateTime类是Java 8中的一个重要类,它表示日期和时间,具有年、月、日、小时、分钟、秒和毫秒等属性。与Date…

    Java 2023年5月26日
    00
  • Java Calendar日历与Date日期的相互转换详解

    下面是“Java Calendar日历与Date日期的相互转换详解”的完整攻略。 标题 Java Calendar日历与Date日期的相互转换详解 概述 Java中常用的时间类型有两种: Calendar和Date。在Java项目中,有时需要在这两种类型之间进行转换。本文将详细介绍如何将Calendar和Date互相转换。 Calendar转换为Date C…

    Java 2023年5月20日
    00
  • Java SpringBoot 中的操作事务

    我们来详细讲解一下Java SpringBoot中的操作事务。 什么是事务 事务是指作为单个逻辑工作单元执行的一系列操作,这些操作要么全部执行,要么全部不执行,如果在执行整个事务时发生错误,会回滚到事务的开始状态,使所有操作都回到事务执行之前的状态。 Spring 中如何使用事务 Spring 提供了一套完整的事务管理机制,其中最基础的是PlatformTr…

    Java 2023年5月19日
    00
  • spring boot过滤器实现项目内接口过滤

    spring boot过滤器实现项目内接口过滤 业务 由于业务需求,存在两套项目,一套是路由中心,一套是业务系统.现在存在问题是,路由中心集成了微信公众号与小程序模块功能,业务系统部署了多套服务.现在需要通过调用路由中心将接口重新路由到指定的业务系统中 需要处理的问题 将小程序,公众号用户信息与业务系统做绑定 将路由中心的接口与业务系统的接口判断出来 通过用…

    Java 2023年4月22日
    00
  • Java反射之类的实例对象的三种表示方式总结

    接下来我将为你详细讲解“Java反射之类的实例对象的三种表示方式总结”的完整攻略。 什么是Java反射? Java反射是指在运行时动态地获取类的信息,并可以通过获取的信息来操作类或对象的属性、方法和构造函数等。Java反射常常被用于泛型操作、动态代理、框架开发、ORM框架等场景中。 类与对象的概念 在讲解Java反射的三种实例对象的表示方式之前,我们需要明确…

    Java 2023年5月26日
    00
  • Spring Cloud Feign 自定义配置(重试、拦截与错误码处理) 代码实践

    下面是关于“Spring Cloud Feign 自定义配置(重试、拦截与错误码处理)”的完整攻略详情。 1. 什么是 Spring Cloud Feign Spring Cloud Feign 是一个声明式 REST 客户端,它使通过 HTTP 通信的服务调用变得更加简单。 Feign 会通过定义接口的方式来注入需要访问的远程服务,这样就可以像调用本地方法…

    Java 2023年5月20日
    00
  • python实现JAVA源代码从ANSI到UTF-8的批量转换方法

    下面是“python实现JAVA源代码从ANSI到UTF-8的批量转换方法”的完整攻略: 1. 安装Python 如果你的电脑上还没有Python,需要先安装Python。 请前往 https://www.python.org/downloads/ 下载并安装Python。 2. 编写Python代码 接下来需要编写Python代码来实现批量转换功能。具体代…

    Java 2023年5月20日
    00
  • 浅谈@RequestMapping注解的注意点

    浅谈@RequestMapping注解的注意点 @RequestMapping注解是Spring MVC中最常用的注解之一,它用于将HTTP请求映射到控制器方法。在本文中,我们将详细讲解@RequestMapping注解的注意点,并提供两个示例来说明这个过程。 注意点 在使用@RequestMapping注解时,我们需要注意以下几点: value属性 @Re…

    Java 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部