纯净、安全、绿色的下载网站

首页

当前位置:首页IT学院IT技术

SpringSecurity过滤器链及Filter Spring Security之默认的过滤器链及自定义Filter操作

咸鱼最牛逼   2021-06-22 我要评论
想了解Spring Security之默认的过滤器链及自定义Filter操作的相关内容吗咸鱼最牛逼在本文为您仔细讲解SpringSecurity过滤器链及Filter的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Spring,Security,默认过滤器链,自定义Filter下面大家一起来学习吧

Spring Security 过滤器链及自定义Filter

别名 类名称 Namespace Element or Attribute
CHANNEL_FILTER ChannelProcessingFilter http/intercept-url@requires-channel
SECURITY_CONTEXT_FILTER SecurityContextPersistenceFilter http
CONCURRENT_SESSION_FILTER ConcurrentSessionFilter session-management/concurrency-control
HEADERS_FILTER HeaderWriterFilter http/headers
CSRF_FILTER CsrfFilter http/csrf
LOGOUT_FILTER LogoutFilter http/logout
X509_FILTER X509AuthenticationFilter http/x509
PRE_AUTH_FILTER AbstractPreAuthenticatedProcessingFilter( Subclasses) N/A
CAS_FILTER CasAuthenticationFilter N/A
FORM_LOGIN_FILTER UsernamePasswordAuthenticationFilter http/form-login
BASIC_AUTH_FILTER BasicAuthenticationFilter http/http-basic
SERVLET_API_SUPPORT_FILTER SecurityContextHolderAwareRequestFilter http/@servlet-api-provision
JAAS_API_SUPPORT_FILTER JaasApiIntegrationFilter http/@jaas-api-provision
REMEMBER_ME_FILTER RememberMeAuthenticationFilter http/remember-me
ANONYMOUS_FILTER AnonymousAuthenticationFilter http/anonymous
SESSION_MANAGEMENT_FILTER SessionManagementFilter session-management
EXCEPTION_TRANSLATION_FILTER ExceptionTranslationFilter http
FILTER_SECURITY_INTERCEPTOR FilterSecurityInterceptor http
SWITCH_USER_FILTER SwitchUserFilter N/A

过滤器顺序从上到下

自定义 Filter

自定义的 Filter 建议继承 GenericFilterBean本文示例:

package com.example.filter;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
/**
 * @author 咸鱼
 * @date 2019-05-26 18:02
 */
public class BeforeLoginFilter extends GenericFilterBean {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("在 UsernamePasswordAuthenticationFilter 前调用");
        chain.doFilter(request, response);
    }
}

配置自定义 Filter 在 Spring Security 过滤器链中的位置

配置很简单本文示例:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/user/**").hasAuthority("USER")
                .and()
                .formLogin().loginPage("/login").defaultSuccessUrl("/user")
                .and()
                .logout().logoutUrl("/logout").logoutSuccessUrl("/login");
        // 在 UsernamePasswordAuthenticationFilter 前添加 BeforeLoginFilter
        http.addFilterBefore(new BeforeLoginFilter(), UsernamePasswordAuthenticationFilter.class);
        // 在 CsrfFilter 后添加 AfterCsrfFilter
        http.addFilterAfter(new AfterCsrfFilter(), CsrfFilter.class);
    }

说明:

HttpSecurity 有三个常用方法来配置:

addFilterBefore(Filter filter, Class<? extends Filter> beforeFilter)

在 beforeFilter 之前添加 filter

addFilterAfter(Filter filter, Class<? extends Filter> afterFilter)

在 afterFilter 之后添加 filter

addFilterAt(Filter filter, Class<? extends Filter> atFilter)

在 atFilter 相同位置添加 filter 此 filter 不覆盖 filter

通过在不同 Filter 的 doFilter() 方法中加断点调试可以判断哪个 filter 先执行从而判断 filter 的执行顺序 

spring security添加自定义过滤器

1、定义自己的过滤器

2、指定位置通过HttpSecurity的方法指定

定义过滤器

package com.qiudaozhang.springsecurity.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RequestHeadCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        var httpRequest = (HttpServletRequest) servletRequest;
        var httpResponse = (HttpServletResponse) servletResponse;
        String requestId = httpRequest.getHeader("Request-id");
        if(requestId == null || requestId.isBlank()) {
            httpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return;
        }
        filterChain.doFilter(servletRequest,servletResponse);
    }
}
package com.qiudaozhang.springsecurity.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RequestParamCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        var httpRequest = (HttpServletRequest) servletRequest;
        var httpResponse = (HttpServletResponse) servletResponse;
        String timestamp = httpRequest.getParameter("timestamp");
        if(timestamp == null || timestamp.isBlank()) {
            httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
            return;
        }
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

指定位置

HttpSecurity中有两个方法指定过滤器的位置一个指定在谁前面一个指定在谁后面

   public HttpSecurity addFilterAfter(Filter filter, Class<? extends Filter> afterFilter) {
       this.comparator.registerAfter(filter.getClass(), afterFilter);
       return this.addFilter(filter);
   }
   public HttpSecurity addFilterBefore(Filter filter, Class<? extends Filter> beforeFilter) {
       this.comparator.registerBefore(filter.getClass(), beforeFilter);
       return this.addFilter(filter);
   }
package com.qiudaozhang.springsecurity.config;
import com.qiudaozhang.springsecurity.filter.RequestHeadCheckFilter;
import com.qiudaozhang.springsecurity.filter.RequestParamCheckFilter;
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;
@Configuration
public class ProjectConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(
                new RequestHeadCheckFilter(),
                BasicAuthenticationFilter.class
        )
                .addFilterAfter(new RequestParamCheckFilter(),BasicAuthenticationFilter.class)
                .authorizeRequests()
                .anyRequest()
                .permitAll();
    }
}

测试

准备一个端点测试

package com.qiudaozhang.springsecurity.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";
    }
}

在这里插入图片描述

当前没有传递timestamp参数所以参照约定过滤器直接给出403.

在这里插入图片描述

当前头部信息和参数信息都提供了检测通过

实际应用场景 检测相关的头部参数等等信息日志过滤器将所有请求的相关数据记录下来特殊的权限校验等等

以上为个人经验希望能给大家一个参考也希望大家多多支持


相关文章

猜您喜欢

  • python openpyxl的使用 python openpyxl如何使用

    想了解python openpyxl怎样使用的相关内容吗临时营地在本文为您仔细讲解python openpyxl的使用的相关知识和一些Code实例欢迎阅读和指正我们先划重点:python,openpyxl,openpyxl的使用下面大家一起来学习吧..
  • java jar打包读取文件失败 解决java项目jar打包后读取文件失败的问题

    想了解解决java项目jar打包后读取文件失败的问题的相关内容吗逝去已末在本文为您仔细讲解java jar打包读取文件失败的相关知识和一些Code实例欢迎阅读和指正我们先划重点:java项目,jar打包,读取文件失败下面大家一起来学习吧..

网友评论

Copyright 2022 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们