ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring Security Filter 学习笔记

2021-12-24 04:35:29  阅读:184  来源: 互联网

标签:http Spring class Filter 过滤器 import Security servlet javax


过滤器可以简单理解成用于拦截请求,并执行相应逻辑的代码。

在Spring Security架构中实现过滤器

在SpringSecurity中,可以通过实现 javax.servlet 包中的 Filter接口构造过滤器。

我们通过实现Filter 接口的doFilter() 方法,执行相关逻辑。该方法包含三个参数:

  1. ServletRequest:表示http请求,可用它获得请求相关信息。
  2. ServletResponse:表示http响应,可向它添加相关信息,最后传回客户端。
  3. FilterChain:表示过滤链,用于把请求和响应转发到过滤链上的下一个过滤器。

Spring Security为我们提供了一些过滤器实现,例如:

  • BasicAuthenticationFilter:用于http认证。
  • CsrfFilter:用于跨请求保护。
  • CorsFilter:负责跨域资源共享 (CORS) 授权规则。

多个过滤器集合在一起形成一条过滤链,它们之间有一定顺序。你可以通过存在于过滤链上的一个过滤器,在它的相对位置添加一个新的过滤器。

在过滤链上的一个过滤器前面,添加一个新的过滤器

可以通过下面的方法在某过滤器前面添加一个新的过滤器。

@Configuration
public class ProjectConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(new CustomFilter(), BasicAuthenticationFilter.class);
    }

}

CustomFilter是你自定义实现的过滤器类,BasicAuthenticationFilter是认证过滤器的默认类型。

在过滤链上的一个过滤器后面,添加一个新的过滤器

下面的代码是在某过滤器后面添加一个新的过滤器。

@Configuration
public class ProjectConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class);
    }

}

在过滤链上的一个过滤器位置,添加一个新的过滤器

下面代码是在一个过滤器的位置上,添加一个新的过滤器。

@Configuration
public class ProjectConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http..addFilterAt(new CustomFilter(), BasicAuthenticationFilter.class);
    }

}

当在一个过滤器的位置上,加入一个新的过滤器,Spring Security不会假设该位置上只有一个过滤器, 它也不会保证该位置上过滤器的顺序。

Spring Security 提供的过滤器实现

Spring Security 提供了一些实现Filter借口的抽象类,并在里面加入一些功能。你可以通过继承这些类来构建过滤器类。例如OncePerRequestFilter等。由于Spring Security不能保证一个过滤器对于同一个请求不会被调用多次,我们可以是过滤器继承OncePerRequestFilter来保证。

演示代码

在过滤器BasicAuthenticationFilter的前面、当前位置、后面各添加一个新的过滤器。

创建一个SpringBoot项目,它的依赖如下:

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

创建三个过滤器,分别为BeforeFilter、CurrentFilter、AfterFilter。

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class BeforeFilter implements Filter {

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    System.out.println("BeforeFilter: " + "在其前面插入的过滤器");
    chain.doFilter(request, response);
  }

}
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class CurrentFilter implements Filter {

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    System.out.println("CurrentFilter: " + "在其当前位置插入的过滤器");
    chain.doFilter(request, response);
  }

}


import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class AfterFilter implements Filter {

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    System.out.println("AfterFilter: " + "在其后面插入的过滤器");
    chain.doFilter(request, response);
  }

}

创建一个配置类ProjectConfig

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import hookind.security009.filter.AfterFilter;
import hookind.security009.filter.BeforeFilter;
import hookind.security009.filter.CurrentFilter;

@Configuration
public class ProjectConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().anyRequest().permitAll();
    // 在前面加入一个过滤器
    http.addFilterBefore(new BeforeFilter(), BasicAuthenticationFilter.class);
    // 在当前位置加入一个过滤器
    http.addFilterAt(new CurrentFilter(), BasicAuthenticationFilter.class);
    // 在其后面加入一个过滤器
    http.addFilterAfter(new AfterFilter(), BasicAuthenticationFilter.class);
  }
}

创建一个Controller类

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
  
  @GetMapping("/hello")
  public String hello(){
    return "Hello";
  }
}

启动程序后,在浏览器输入网址 http://localhost:8080/hello,我的控制台输出如下:

BeforeFilter: 在其前面插入的过滤器
CurrentFilter: 在其当前位置插入的过滤器
AfterFilter: 在其后面插入的过滤器
BeforeFilter: 在其前面插入的过滤器
CurrentFilter: 在其当前位置插入的过滤器
AfterFilter: 在其后面插入的过滤器
BeforeFilter: 在其前面插入的过滤器
CurrentFilter: 在其当前位置插入的过滤器
AfterFilter: 在其后面插入的过滤器

由上可知,过滤器是按BeforeFilter、CurrentFilter、AfterFilter顺序调用的。也表示,对于同一个请求,Spring Security可能会调用同一个过滤器多次。

标签:http,Spring,class,Filter,过滤器,import,Security,servlet,javax
来源: https://www.cnblogs.com/hookind/p/15725827.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有