当前位置: 首页 > news >正文

Spring-Security-5.7.11升级6.5.2

1.Session Management

1.1.必须明确调用SecurityContextRepository保存SecurityContext

在Spring Security 5中,默认行为是SecurityContext使用SecurityContextPersistenceFilter自动保存到SecurityContextRepository

//版本5.7.11
//SecurityContextPersistenceFilter中核心代码
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);SecurityContext contextBeforeChainExecution = this.repo.loadContext(holder);try {SecurityContextHolder.setContext(contextBeforeChainExecution);//...}finally {SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext();SecurityContextHolder.clearContext();// 保存this.repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse());}

SecurityContextPersistenceFilter已被作废

在Spring Security 6中,默认行为是SecurityContextHolderFilter只会从SecurityContextRepository读取SecurityContext并将其填充到SecurityContextHolder中。如果用户希望SecurityContext在请求之间保持不变,他们现在必须使用SecurityContextRepository显式保存SecurityContext

//版本6.5.2
private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)throws ServletException, IOException {Supplier<SecurityContext> deferredContext = this.securityContextRepository.loadDeferredContext(request);try {this.securityContextHolderStrategy.setDeferredContext(deferredContext);chain.doFilter(request, response);}finally {// 没有保存this.securityContextHolderStrategy.clearContext();request.removeAttribute(FILTER_APPLIED);}}

1.2.登录成功的通用保存逻辑

如果是登录成功,根据不同的登录方式设置,以下是必须要设置的

// 版本6.5.2
SecurityContext context = this.securityContextHolderStrategy.createEmptyContext();
context.setAuthentication(authenticationResult);
this.securityContextHolderStrategy.setContext(context);
this.securityContextRepository.saveContext(context, request, response);

用户名密码登录可参见AbstractAuthenticationProcessingFilter

//版本5.7.11
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,Authentication authResult) throws IOException, ServletException {SecurityContext context = SecurityContextHolder.createEmptyContext();context.setAuthentication(authResult);SecurityContextHolder.setContext(context);this.securityContextRepository.saveContext(context, request, response);if (this.logger.isDebugEnabled()) {this.logger.debug(LogMessage.format("Set SecurityContextHolder to %s", authResult));}this.rememberMeServices.loginSuccess(request, response, authResult);if (this.eventPublisher != null) {this.eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));}this.successHandler.onAuthenticationSuccess(request, response, authResult);}
​
// 版本6.5.2
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder.getContextHolderStrategy();
​
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,Authentication authResult) throws IOException, ServletException {//创建SecurityContext的对象不同SecurityContext context = this.securityContextHolderStrategy.createEmptyContext();context.setAuthentication(authResult);this.securityContextHolderStrategy.setContext(context);// 显示保存this.securityContextRepository.saveContext(context, request, response);if (this.logger.isDebugEnabled()) {this.logger.debug(LogMessage.format("Set SecurityContextHolder to %s", authResult));}this.rememberMeServices.loginSuccess(request, response, authResult);if (this.eventPublisher != null) {this.eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));}this.successHandler.onAuthenticationSuccess(request, response, authResult);}

1.3.SecurityContextRepository默认的初始化

//版本6.5.2
HttpSessionSecurityContextRepository httpSecurityRepository = new HttpSessionSecurityContextRepository();
DelegatingSecurityContextRepository defaultRepository = new DelegatingSecurityContextRepository(httpSecurityRepository, new RequestAttributeSecurityContextRepository());
return defaultRepository;
​
//版本5.7.11
HttpSessionSecurityContextRepository httpSecurityRepository; = new HttpSessionSecurityContextRepository();
return httpSecurityRepository;

1.4.SecurityContextRepository的接口

public interface SecurityContextRepository {
​//5.7.11中使用的接口@DeprecatedSecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder);
​//最新6.5.2中使用接口,目前兼容,作废的loadContext后续会被删除default DeferredSecurityContext loadDeferredContext(HttpServletRequest request) {Supplier<SecurityContext> supplier = () -> loadContext(new HttpRequestResponseHolder(request, null));return new SupplierDeferredSecurityContext(SingletonSupplier.of(supplier),SecurityContextHolder.getContextHolderStrategy());}
​void saveContext(SecurityContext context, HttpServletRequest request, HttpServletResponse response);
​
​boolean containsContext(HttpServletRequest request);
}

2.csrf的token

 private CsrfTokenRepository tokenRepository;
​
//5.7.11通过一下方法获取
CsrfToken token = tokenRepository.loadToken(request);
if (token != null) {userDetails.getUserDTO().setToken(token.getToken());
}
​
//6.5.2使用以下方式
DeferredCsrfToken token = tokenRepository.loadDeferredToken(request, response);
if (token != null) {userDetails.getUserDTO().setToken(token.get().getToken());
}

3.授权

//5.7.11 使用以下方式 在6中已被标记作废
FilterSecurityInterceptor AccessDecisionManager//6.5.2 已通过
AuthorizationManager控制public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry authorizationManagerRequestMatcherRegistry) {HttpSecurity http = authorizationManagerRequestMatcherRegistry.and();
​AuthorizationManager<RequestAuthorizationContext> requestAuthorizationManager =  new xxxx
​authorizationManagerRequestMatcherRegistry.requestMatchers(accessRequestMatcherToArray()).access(xxRequestAuthorizationManager);
}  

4.SecurityFilterChain的配置

<1>HttpSecurity中的apply方法将被作废

//升级前   
http.apply(xxxCaptchaVerifier())
//升级后    
http.with(xxxCaptchaVerifier(), withDefaults())

<2>xxExceptionHandlingCustomizerand方法将被作废,主要获取HttpSecurity,然后获取ApplicationContext,获取Bean

// 升级前
public class XxExceptionHandlingCustomizer extends XxAbstractCustomizer<ExceptionHandlingConfigurer<HttpSecurity>> {@Overridepublic void customize(ExceptionHandlingConfigurer<HttpSecurity> exceptionHandlingConfigurer) {//.and()已作废HttpSecurity http = exceptionHandlingConfigurer.and();Http401UnauthorizedEntryPoint http401UnauthorizedEntryPoint = getBean(http, Http401UnauthorizedEntryPoint.class);}
}// 升级后
public class XxExceptionHandlingCustomizer extends XxAbstractCustomizer<ExceptionHandlingConfigurer<HttpSecurity>> {public XxExceptionHandlingCustomizer(ApplicationContext context) {super(context);}@Overridepublic void customize(ExceptionHandlingConfigurer<HttpSecurity> exceptionHandlingConfigurer) {Http401UnauthorizedEntryPoint http401UnauthorizedEntryPoint = getBean(Http401UnauthorizedEntryPoint.class);exceptionHandlingConfigurer.authenticationEntryPoint(http401UnauthorizedEntryPoint);}}

<3>HttpSecurity中多个配置不在使用and方法,统一使用Customizer<T>接口配置

//升级前
http.cors().and().securityContext(xxxSecurityContextCustomizer())    //升级后     //只开启cors,不自定义配置
http.cors(withDefaults());
//开启cors,自定义配置   
http.cors(corsConfigurer -> {})

http://www.xdnf.cn/news/1283005.html

相关文章:

  • 机器学习-决策树(DecisionTree)
  • YOLOv6深度解析:实时目标检测的新突破
  • GESP2023年9月认证C++一级( 第三部分编程题(1)买文具)
  • vue3-pinia
  • 在 Ubuntu 中docker容器化操作来使用新建的 glibc-2.32
  • SQL 基础查询语句详解
  • Pytest项目_day12(yield、fixture的优先顺序)
  • 论文学习22:UNETR: Transformers for 3D Medical Image Segmentation
  • MFC C++ 使用ODBC方式调用Oracle数据库的详细步骤
  • 北京朝阳区中小学生信息学竞赛选拔赛C++真题
  • 电子电气架构 --- 软件定义汽车的驱动和挑战
  • [Element-plus]动态设置组件的语言
  • Oracle数据库中的Library cache lock和pin介绍
  • Redis 数据结构及特点
  • VMD例程(Matlab 2021b可直接使用)
  • C++方向知识汇总(三)
  • 【MySQL基础篇】:MySQL索引——提升数据库查询性能的关键
  • 【华为机试】648. 单词替换
  • Jmeter使用第二节-接口测试(Mac版)
  • Nestjs框架: RBAC基于角色的权限控制模型初探
  • Flutter - 应用启动/路由管理
  • buildroot编译qt 5.9.8 arm64版本踩坑
  • 个人效能是一个系统
  • MaixPy简介
  • MySQL 函数
  • 达梦数据库慢SQL日志收集和分析
  • 【排序算法】⑥快速排序:Hoare、挖坑法、前后指针法
  • 算法训练营DAY57 第十一章:图论part07
  • 数集相等定义凸显解析几何几百年重大错误:将无穷多各异点集误为同一集
  • 深度学习和神经网络最基础的mlp,从最基础的开始讲