springsecurity6使用

spring security 中的类 :

  • AuthenticationManager : 实现类:ProviderManager
    管理很多的 provider ,,, 经常使用的,DaoAuthenticationProvider , 这个要设置一个 UserDetailService , 查找数据库,,loadUserByUsername() 查找出数据库中的对象,,然后进行比对
spring security 中的配置

配置spring security 也就是配置 过滤器链,,spring security 他有默认的过滤器链,,,通过HttpSecurity 中的 build()方法,会返回一个默认的有拦截的过滤器链
我们一般都是在这个原本的过滤器链上面修改,,而不是重新创建自己的过滤器链,,

/*** 过滤器*  : 配置过滤器链*  DispatchServlet**  DefaultLoginPageGeneratingFilter : 默认登录页面过滤器*  DefaultLogoutPageGeneratingFilter : 默认注销页面过滤器*  BasicAuthenticationFilter : 请求头认证过滤器*//*** 配置过滤器链  SecurityFilterChain,,spring security 所有功能都是通过过滤器链来提供*/@BeanSecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {// 拦截所有,,经过某些过滤器
//        return new DefaultSecurityFilterChain(new AntPathRequestMatcher("/**"));// 默认的过滤器链
//        return http.build();http.authorizeHttpRequests(p->p.anyRequest().authenticated()).formLogin(f->f.usernameParameter("username").passwordParameter("password").loginProcessingUrl("/login").successHandler((req,resp,auth)->{resp.setContentType("application/json;charset=utf-8");Hr hr = (Hr) auth.getPrincipal();hr.setPassword(null);resp.getWriter().write(new ObjectMapper().writeValueAsString(RespBean.ok("登录成功",hr)));}).failureHandler((req,resp,e)->{resp.setContentType("application/json;charset=utf-8");RespBean error = RespBean.error("登录失败");if (e instanceof BadCredentialsException){error.setMessage("密码错误");}else if (e instanceof DisabledException){error.setMessage("用户被禁用");}else if (e instanceof LockedException){error.setMessage("账户被锁定");}else if (e instanceof AccountExpiredException){error.setMessage("账户过期");}else if(e instanceof CredentialsExpiredException){error.setMessage("密码过期");}resp.getWriter().write(new ObjectMapper().writeValueAsString(error));})).csrf(c->c.disable())//异常处理.exceptionHandling(e->e.authenticationEntryPoint((req,resp,ex)->{resp.setContentType("application/json;charset=utf-8");resp.setStatus(401);RespBean error = RespBean.error("尚未登陆,请登录");resp.getWriter().write(new ObjectMapper().writeValueAsString(error));}));// 加到 UsernamePasswordAuthenticationFilter前面http.addFilterBefore(jsonFilter(), UsernamePasswordAuthenticationFilter.class);return  http.build();/*** spring security 默认key-value* UsernamePasswordAuthenticationFilter*/}

UsernamePasswordAuthenticationFilter : 这个是拦截提交的用户名密码的拦截器,,,里面有个attemptAuthentication() 去获取前端传入的用户名密码,
在这里插入图片描述
根据request获取的参数,,,
然而,我们需要通过json传参,,就需要重写这个方法,,并将自己的过滤器加入到spring security的过滤器链中,,

/*** 登录传递json*/
public class JsonFilter extends UsernamePasswordAuthenticationFilter {@Overridepublic Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {if (!request.getMethod().equals("POST")) {throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());}String contentType = request.getContentType();if (contentType.equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE) || contentType.equalsIgnoreCase(MediaType.APPLICATION_JSON_UTF8_VALUE)){// 前端传入的是jsontry {// 通过io流,去解析请求体参数,,,比如:文件,json,,,   key-value也可以通过io流获取Hr hr = new ObjectMapper().readValue(request.getInputStream(), Hr.class);String username = hr.getUsername();String password = hr.getPassword();UsernamePasswordAuthenticationToken authRequest = UsernamePasswordAuthenticationToken.unauthenticated(username,password);// Allow subclasses to set the "details" propertysetDetails(request, authRequest);// 获取认证管理器去认证return this.getAuthenticationManager().authenticate(authRequest);} catch (IOException e) {throw new RuntimeException(e);}}else{//  key-valuereturn super.attemptAuthentication(request,response);}}
}

自己新加的过滤器,需要配置自己的 AuthenticationManager , 和用户信息存放的位置:

   /*** AuthenticationManager :*      实现类:   ProviderManager*      管理很多 provider* @return*/@BeanAuthenticationManager authenticationManager(){DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();daoAuthenticationProvider.setUserDetailsService(hrService);ProviderManager providerManager = new ProviderManager(daoAuthenticationProvider);return providerManager;}

配置了自己的 登录filter,, HttpSecurity中配置的formLogin 就失效了,,,需要自己配置loginProcessingUrl, successHandler,failureHandler等信息,,

需要配置自己的 AuthenticationManager 和表明登录信息的存放位子,,,,因为每一次都会从这个存放位置去找用户信息,,如果找到,表示已登录,如果没找到,就是没有登录

   /*** 配置了  JsonFilter ,,,    httpsecurity 中的 fromLogin就失效了* @return*/JsonFilter jsonFilter(){JsonFilter jsonFilter = new JsonFilter();jsonFilter.setFilterProcessesUrl("/login");jsonFilter.setAuthenticationSuccessHandler((req,resp,auth)->{resp.setContentType("application/json;charset=utf-8");Hr hr = (Hr) auth.getPrincipal();hr.setPassword(null);resp.getWriter().write(new ObjectMapper().writeValueAsString(RespBean.ok("登录成功",hr)));});jsonFilter.setAuthenticationFailureHandler((req,resp,e)->{resp.setContentType("application/json;charset=utf-8");RespBean error = RespBean.error("登录失败");if (e instanceof BadCredentialsException){error.setMessage("密码错误");}else if (e instanceof DisabledException){error.setMessage("用户被禁用");}else if (e instanceof LockedException){error.setMessage("账户被锁定");}else if (e instanceof AccountExpiredException){error.setMessage("账户过期");}else if(e instanceof CredentialsExpiredException){error.setMessage("密码过期");}resp.getWriter().write(new ObjectMapper().writeValueAsString(error));});// 需要设置自己的 AuthenticationManagerjsonFilter.setAuthenticationManager(authenticationManager());/***  每一次都会从 httpSession中获取用户,,如果httpsession中没有用户,就会表示成没有登录,,*  新配置的 filter 需要告知 ,,用户信息存放在哪里,,*/// 自己配置的filter 需要设置 SecurityContextHolder 存储用户的位置jsonFilter.setSecurityContextRepository(new HttpSessionSecurityContextRepository());return jsonFilter;}

这个用户信息可以存在HttpSessionSecurityContextRepositorysession中,,也可以重写类,存放在其他地方,比如redis

spring security 异常处理,,exceptionHandling, 中authenticationEntryPoint,处理登录失败异常
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/469748.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在python中JSON数据格式的使用

什么是JSON? JSON是一种数据格式,由美国程序设计师DouglasCrockford创建的,JSON全名是JavaScript Object Notation,由JSON英文全文字义我们可以推敲JSON的缘由,最初是为JavaScript开发的。这种数据格式由于简单好用被大量应用在We…

数据分析案例-基于亚马逊智能产品评论的探索性数据分析

🤵‍♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞&#x1f4…

PHP脉聊交友系统网站源码,可通过广告变现社交在线聊天交友即时通讯APP源码,附带视频搭建教程

探索全新社交体验:一站式PHP交友网站解决方案 🌐 全球化交友,无界沟通 在数字化的浪潮下,社交已不再受地域限制。我们的PHP交友网站不仅支持多国语言,还配备了即时翻译功能,让您轻松跨越语言障碍&#xff…

JVM(1)基础篇

1 初始JVM 1.1 什么是JVM JVM 全称是 Java Virtual Machine,中文译名 Java虚拟机。JVM 本质上是一个运行在计算机上的程序,他的职责是运行Java字节码文件。 Java源代码执行流程如下: 分为三个步骤: 编写Java源代码文件。 使用…

【并发编程】ThreadPoolExecutor类

📝个人主页:五敷有你 🔥系列专栏:并发编程⛺️稳重求进,晒太阳 ThreadPoolExecutor 1) 线程池状态 ThreadPoolExecutor 使用 int 的高 3 位来表示线程池状态,低 29 位表示线程数量 状态名 高三位 …

Spring Boot 笔记 021 项目部署

1.1 引入坐标,并双击package打包成jar包 1.2 在服务器上运行jar包 1.3 使用postman测试 2.1 运行配置 2.1.1 命令更改端口 java -jar big-event-1.0-SNAPSHOT.jar --server.port7777 2.1.2 环境变量更新(略) 2.1.3 外部配置文件&#xff0c…

算法沉淀——栈(leetcode真题剖析)

算法沉淀——栈 01.删除字符串中的所有相邻重复项02.比较含退格的字符串03.基本计算器 II04.字符串解码05.验证栈序列 栈(Stack)是一种基于先进后出(Last In, First Out,LIFO)原则的数据结构。栈具有两个主要的操作&am…

幻兽帕鲁游戏联机的时候,显示“网络连接超时”怎么解决?

如果你在游戏联机的时候,显示“网络连接超时”,可以检查下: 1、前提是你已经按照教程部署成功 2、检查防火墙有没有忘记设置,协议是UDP(只有TCP不行,一定要有UDP),端口是否填了8211&…

java数据结构与算法刷题-----LeetCode459. 重复的子字符串

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 本题的高效解法,需要使用KMP算法中,NEXT数组的处理…

库函数strlen的实现

目录 一、原理二、思路三、实现 一、原理 库函数strlen的功能是求字符串长度,统计的是字符串中 \0 之前的字符的个数。 函数原型如下: size_t strlen ( const char * str );二、思路 参数str接收⼀个字符串的起始地址,然后开始统计字符串中…

推荐《架构探险:从零开始写Java Web框架》

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl 春节读了《架构探险:从零开始写Java Web框架》,一本大概10年前的好书。 本书的作者是阿里巴巴架构师黄勇。黄勇对分布式服务架构与大数据技术有深入…

Python算法题集_二叉树的最大深度

Python算法题集_二叉树的最大深度 题104:二叉树的最大深度1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【DFS自顶向下】2) 改进版一【DFS自底向上】3) 改进版二【BFS】 4. 最优算法 本文为Python算法题集之一的代码示例 题104&am…