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

网友投稿 250 2023-01-04

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中有两个方法,指定过滤器的位置,一个指定在谁前面,一个指定在谁后面。http://

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(filteQsLoYvkr);

}

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.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.

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

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:免费的api接口网站(免费的 API 接口服务)
下一篇:调用解析api接口教程(解析API)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~