springboot 整合 Spring Security 上篇

1.创建springBoot 项目工程(spring6.0的底层、JDK17)

1.添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>

配置完成启动访问controller会出现登录页面
在这里插入图片描述

默认用户user 密码 控制台uuid输出,跟踪源码可以看到
在这里插入图片描述

2 使用配置的用户名密码;
  security:user:name: adminpassword: 123456

使用自己配置的登录然后就可以访问控制层api

3.退出登录

http://127.0.0.1:8080/logout
在这里插入图片描述

2.基于内存的多用户管理

在这里插入图片描述

1.创建用户详情接口配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;//自定义配置类实现用户详情
@Configuration
public class MyUserSecurityConfig {@Beanpublic UserDetailsService userDetailsService() {UserDetails user1 = User.builder().username("admin").password("123456").build();UserDetails user2 = User.builder().username("test").password("123456").build();InMemoryUserDetailsManager memoryUserDetailsManager = new InMemoryUserDetailsManager();memoryUserDetailsManager.createUser(user1);memoryUserDetailsManager.createUser(user2);return memoryUserDetailsManager;}}

访问接口登录 test test 报错:如下
在这里插入图片描述
必须加密
修改配置类

package com.example.db.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;//自定义类实现用户详情接口
@Configuration
public class MyUserSecurityConfig {@Beanpublic UserDetailsService userDetailsService() {UserDetails user1 = User.builder().username("admin").password("123456").roles("admin").build();UserDetails user2 = User.builder().username("test").password("123456").roles("stu").build();InMemoryUserDetailsManager memoryUserDetailsManager = new InMemoryUserDetailsManager();memoryUserDetailsManager.createUser(user1);memoryUserDetailsManager.createUser(user2);return memoryUserDetailsManager;}//配置密码加密器//没有加密NoOpPasswordEncoder@Beanpublic PasswordEncoder passwordEncoder() {return NoOpPasswordEncoder.getInstance();}}

通过上面配置可以正常登录,访问api接口,配置文件中的用户失效

3.密码加密

1.CSDN密码泄露事件,数据库明文存储
1.前端密码加密给后端,使用相同的密码加密规则,前端加密对比数据库密码校验规则。

常见加密算法MD5 sha RSA

2、使用PasswordEncoder接口提供的实现类

加盐干扰因子
BCryptPasswordEncoder 加密和校验原始密码

BCryptPasswordEncoder cryptPasswordEncoder=new BCryptPasswordEncoder();String encode = cryptPasswordEncoder.encode("123456");String encode2 = cryptPasswordEncoder.encode("123456");String encode3 = cryptPasswordEncoder.encode("123456");log.info(encode);log.info(encode2);log.info(encode3);boolean pwd1 = cryptPasswordEncoder.matches("123456", encode);boolean pwd2 = cryptPasswordEncoder.matches("123456", encode2);boolean pwd3 = cryptPasswordEncoder.matches("123456", encode3);log.info("pwd1="+pwd1);log.info("pwd2="+pwd2);log.info("pwd3="+pwd3);

在这里插入图片描述
加密上面文明密码


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;//自定义类实现用户详情接口
@Configuration
public class MyUserSecurityConfig {@Beanpublic UserDetailsService userDetailsService() {UserDetails user1 = User.builder().username("admin").password(passwordEncoder().encode("123456")).roles("admin").build();UserDetails user2 = User.builder().username("test").password(passwordEncoder().encode("654321")).roles("stu").build();InMemoryUserDetailsManager memoryUserDetailsManager = new InMemoryUserDetailsManager();memoryUserDetailsManager.createUser(user1);memoryUserDetailsManager.createUser(user2);return memoryUserDetailsManager;}//配置密码加密器//没有加密NoOpPasswordEncoder@Beanpublic PasswordEncoder passwordEncoder() {
//        return NoOpPasswordEncoder.getInstance();return new BCryptPasswordEncoder();}}在这里插入代码片

返回登录信息测试
添加控制器

package com.example.db.control;import org.springframework.boot.autoconfigure.neo4j.Neo4jProperties;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.security.Principal;@RestController
@RequestMapping("/user")
public class UserController {@GetMapping("/loginUser")public Authentication loginUser(Authentication authentication) {return authentication;}@GetMapping("/loginUser2")public Principal loginUser2(Principal principal) {return principal;}@GetMapping("/loginUser3")public Principal loginUser3() {//通过安全上下文持有器Authentication authentication = SecurityContextHolder.getContext().getAuthentication();return authentication;}
}

访问接口返回登录用户的信息如下
在这里插入图片描述
配置权限

UserDetails user1 = User.builder().username("admin").password(passwordEncoder().encode("123456")).roles("admin").authorities("stu:del") //配置权限
{"authorities": [{"authority": "stu:del"}],"details": {"remoteAddress": "127.0.0.1","sessionId": "026ED34E46FC9022C29B200090F14924"},"authenticated": true,"principal": {"password": null,"username": "admin","authorities": [{"authority": "stu:del"}],"accountNonExpired": true,"accountNonLocked": true,"credentialsNonExpired": true,"enabled": true},"credentials": null,"name": "admin"
}
4.基于方法的授权

开启@EnableGlobalMethodSecurity(prePostEnabled = true)

package com.example.db.config;import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.web.SecurityFilterChain;import static org.springframework.security.config.Customizer.withDefaults;//从 Spring Security 5.7.0-M2开始 WebSecurityConfigurerAdapter 被标记为过期,鼓励用户转向基于组件的 security 配置
@Configuration
@Slf4j
//全局方法授权@EnableWebSecurity  // 启用SpringSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration {@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.anyRequest().authenticated());http.formLogin().permitAll();return http.build();}@Beanpublic WebSecurityCustomizer webSecurityCustomizer() {return (web) -> web.ignoring().requestMatchers("/test/**");}}

控制器配置

package com.example.db.control;import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RequestMapping("/student")
@RestController
public class StudentController {@GetMapping("/stu")@PreAuthorize("hasAuthority('stu')")public String test() {return "I am a student";}
}

5.处理结果返回JSON 前端好处理

响应报文VO

package com.example.db.pojo;import lombok.Data;/*** 自定义响应结构*/
@Data
public class Result {// 响应业务状态private Integer code;// 响应消息private String message;// 响应中的数据private Object data;public Result() {}public Result(Object data) {this.code = 200;this.message = "OK";this.data = data;}public Result(String message, Object data) {this.code = 200;this.message = message;this.data = data;}public Result(Integer code, String message, Object data) {this.code = code;this.message = message;this.data = data;}public static Result ok() {return new Result(null);}public static Result ok(String message) {return new Result(message, null);}public static Result ok(Object data) {return new Result(data);}public static Result ok(String message, Object data) {return new Result(message, data);}public static Result build(Integer code, String message) {return new Result(code, message, null);}public static Result build(Integer code, String message, Object data) {return new Result(code, message, data);}}
1.认证成功处理
package com.example.db.config;import com.example.db.pojo.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;import java.io.IOException;//认证成功处理器
@Component
@Slf4j
public class AuthorSuccesssHandler implements AuthenticationSuccessHandler {@Autowiredprivate ObjectMapper objectMapper;@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {Result result=Result.build(1,"登录成功");String responsejson=objectMapper.writeValueAsString(result);response.setCharacterEncoding("utf-8");response.setContentType("application/json;charset=UTF-8");response.getWriter().println(responsejson);response.getWriter().flush();}
}

在这里插入图片描述

2.认证失败处理器
package com.example.db.config;import com.example.db.pojo.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;import java.io.IOException;
//认证失败处理器
@Componentpublic class AuthorFailHandler implements AuthenticationFailureHandler {@Autowiredprivate ObjectMapper objectMapper;@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {Result result=Result.build(-1,"登陆失败");String responsejson=objectMapper.writeValueAsString(result);response.setCharacterEncoding("utf-8");response.setContentType("application/json;charset=UTF-8");response.getWriter().println(responsejson);response.getWriter().flush();}
}

在这里插入图片描述

3.退出登录处理器
package com.example.db.config;import com.example.db.pojo.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;import java.io.IOException;//注销处理器
@Component
@Slf4j
public class AppLoginOutHandler implements LogoutSuccessHandler {@Autowiredprivate ObjectMapper objectMapper;@Overridepublic void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {Result result = Result.build(1, "退出登录成功");String responsejson = objectMapper.writeValueAsString(result);response.setCharacterEncoding("utf-8");response.setContentType("application/json;charset=UTF-8");response.getWriter().println(responsejson);response.getWriter().flush();}
}

在这里插入图片描述

4.资源访问拒绝处理器
package com.example.db.config;import com.example.db.pojo.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;import java.io.IOException;//资源访问拒绝处理器
@Slf4j
@Component
public class AppAcessDeiedHandler implements AccessDeniedHandler {@Autowiredprivate ObjectMapper objectMapper;@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {Result result = Result.build(0, "你没有权限访问资源");String responsejson = objectMapper.writeValueAsString(result);response.setCharacterEncoding("utf-8");response.setContentType("application/json;charset=UTF-8");response.getWriter().println(responsejson);response.getWriter().flush();}
}

在这里插入图片描述

5.配置各种处理器
package com.example.db.config;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.web.SecurityFilterChain;//从 Spring Security 5.7.0-M2开始 WebSecurityConfigurerAdapter 被标记为过期,鼓励用户转向基于组件的 security 配置
@Configuration
@Slf4j
//全局方法授权@EnableWebSecurity  // 启用SpringSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration {//认证成功处理器@Autowiredprivate AuthorSuccesssHandler authorSuccesssHandler;@Autowired//认证失败处理器private AuthorFailHandler authorFailHandler;//退出登录处理器@Autowiredprivate AppLoginOutHandler appLoginOutHandler;//访问拒绝处理器@Autowiredprivate AppAcessDeiedHandler appAcessDeiedHandler;@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.anyRequest().authenticated());http.formLogin().successHandler(authorSuccesssHandler)//认证成功.failureHandler(authorFailHandler)//认证失败.permitAll();http.logout().logoutSuccessHandler(appLoginOutHandler); //退出登录http.exceptionHandling().accessDeniedHandler(appAcessDeiedHandler);//访问资源失败return http.build();}@Beanpublic WebSecurityCustomizer webSecurityCustomizer() {return (web) -> web.ignoring().requestMatchers("/test/**");}}

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

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

相关文章

prometheus部署及与grafana结合应用

一、prometheus 介绍 prometheus server 是 Prometheus组件中的核心部分&#xff0c;负责实现对监控数据的获取&#xff0c;存储以及查询。它会定期从静态配置的监控目标或者基于服务发现自动配置的自标中进行拉取数据&#xff0c;当新拉取到的数据大于配置的内存缓存区时&…

绘制彩色正多边形-第11届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第10讲。 绘制彩色正多边形…

论文解读--Visual Lane Tracking and Prediction for Autonomous Vehicles

自动驾驶汽车视觉车道线跟踪和预测 摘要 我们提出了一种用于自动驾驶汽车跟踪水平道路车道标记位置的可视化方法。我们的方法是基于预测滤波的。预测步骤估计在每个新的图像帧中期望的车道标记位置。它也是基于汽车的运动学模型和嵌入式测程传感器产生的信息。使用适当准备的测…

弱网模拟工具

一、背景 一个人晚上在家通过 Wi-Fi 上网&#xff0c;在线电影播放基本流畅&#xff0c;可一旦在晚间用网高峰期打视频电话就画面糊&#xff0c;这时不仅可能带宽受限了&#xff0c;还可能有较高的丢包率。与有线网络通信相比&#xff0c;无线网络通信受环境影响会更大&#x…

【Java Web学习笔记】 1 - HTML入门

项目代码 https://github.com/yinhai1114/JavaWeb_LearningCode/tree/main/html 零、网页的组成 HTML是网页内容的载体。内容就是网页制作者放在页面上想要让用户浏览的信息&#xff0c;可以包含文字、图片视频等。 CSS样式是表现。就像网页的外衣。比如&#xff0c;标题字体、…

树基本概念+前中后序遍历二叉树

&#x1f308;一、树的基本概念 ☀️1.树的定义&#xff1a;树是一种非线性结构&#xff0c;看起来像一棵倒挂的树&#xff0c;根朝上&#xff0c;而叶朝下。 ☀️2.相关术语 1.根节点&#xff1a;图中的A&#xff0c;无前驱结点 2.叶节点&#xff08;终端节点&#xff09;&a…

第九节HarmonyOS 常用基础组件4-Button

一、Button Button组件主要用来响应点击操作&#xff0c;可以包含子组件。 示例代码&#xff1a; Entry Component struct Index {build() {Row() {Column() {Button(确定, { type: ButtonType.Capsule, stateEffect: true }).width(90%).height(40).fontSize(16).fontWeigh…

Java类的初始化顺序

类初始化顺序遵循以下三个原则&#xff08;优先级依次递减&#xff09; 1、静态对象&#xff08;变量&#xff09;优先于非静态对象&#xff08;变量&#xff09;初始化&#xff0c;其中静态对象&#xff08;变量&#xff09;只初始化一次&#xff0c;而非静态对象&…

【海思SS528 | VO】MPP媒体处理软件V5.0 | 视频输出模块——学习笔记

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

谈谈MYSQL索引

基本介绍 索引是帮助MySQL高效获取数据的数据结构&#xff0c;主要是用来提高数据检索的效率&#xff0c;降低数据库的IO成本&#xff0c;同时通过索引列对数据进行排序&#xff0c;降低数据排序的成本&#xff0c;也能降低了CPU的消耗。 通俗来说, 索引就相当于一本书的目录,…

WebGL笔记:图形缩放的原理和实现

缩放 1 &#xff09;原理 缩放可以理解为对向量长度的改变&#xff0c;或者对向量坐标分量的同步缩放 如下图&#xff0c;比如让向量OA 收缩到点B的位置&#xff0c;也就是从OA变成OB&#xff0c;缩放了一半 2 &#xff09;公式 已知 点A的位置是(ax,ay,az)点A基于原点內缩了…

Redis 入门、基础。(五种基本类型使用场景)

文章目录 1. 概况1.1 认识 NoSQL1.1.1 查询方式1.1.2 事务1.1.3 总结 2. 认识 Redis4. Redis 常见命令4.1 Redis 数据结构介绍4.2 Redis 通用命令4.3 Redis 命令之 String 命令4.4 Redis 命令的层级结构4.5 Redis 命令之 Hash 命令4.6 Redis 命令之 List 命令4.7 set 唯一不排序…

SparkSQL远程调试(IDEA)

启动Intellij IDEA&#xff0c;打开spark源码项目&#xff0c;配置远程调试 Run->Edit Configuration 启动远程spark-sql spark-sql --verbose --driver-java-options "-Xdebug -Xrunjdwp:transportdt_socket,servery,suspendy,address5005"参数说明&#xff1a;…

css实现简单的抽奖动画效果和旋转效果,还有春联效果

使用css的animation和transform和transition可以实现简单的图片放大缩小&#xff0c;旋转&#xff0c;位移的效果&#xff0c;由此可以延伸的动画效果还是挺多的&#xff0c;比如图片慢慢放大&#xff0c;图片慢慢旋转并放大&#xff0c;图片慢慢变化位置等等&#xff0c; 抽奖…

重新认识Word——样式

重新认识Word Word样式给所有一级标题加上一级标题样式修改标题一样式&#xff0c;符合要求 正文样式标题前的小黑点导航窗格样式的相互复制Word一键转PPT 话说回来&#xff0c;一个程序员平时可能还看不起office全家桶的软件&#xff0c;但是&#xff0c;在实际的生活运用中&a…

springboot 整合 RocketMQ 可用于物联网,电商高并发场景下削峰,保证系统的高可用

本文根据阿里云 RocketMQ产品文档整理&#xff0c;地址:https://help.aliyun.com/document_detail/29532.html?userCodeqtldtin2 RocketMQ是由阿里捐赠给Apache的一款低延迟、高并发、高可用、高可靠的分布式消息中间件。经历了淘宝双十一的洗礼。RocketMQ既可为分布式应用系统…

内部培训平台的系统 PlayEdu搭建私有化内部培训平台

PlayEdu是由白书科技团队多年经营的线上教育系统&#xff0c;专为企业提供的全新企业培训方案 我们的目标是为更多的企业机构搭建私有化内部培训平台&#xff0c;以满足不断增长的培训需求 通过PlayEdu&#xff0c;企业可以有效地组织和管理培训资源&#xff0c;提供高质量的…

分类详情 API 返回值说明

为了进行此平台API的调用&#xff0c;首先我们需要做下面几件事情。 1、 获取一个KEY&#xff0c;点击获取测试key和secret 2、 参考API文档里的接入方式和示例。 3、查看测试工具是否有需要的接口&#xff0c;响应实例的返回字段是否符合参数要求。 4、利用平台的文档中心…

[前 5 名] 最顶级的数据恢复软件解决方案列表

您是否在互联网上找到适用于 Windows PC 的前 5 名最受好评的数据恢复软件解决方案&#xff1f;嗯&#xff0c;在线市场上有很多工具可以恢复已删除的文件。但并不是所有的应用程序都值得使用它。值得信赖的文件恢复工具将有助于快速检索丢失、删除、格式化的数据并从计算机恢复…

JVM之基本概念(一)

(1) 基本概念&#xff1a; JVM 是可运行 Java 代码的假想计算机 &#xff0c;包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收&#xff0c;堆 和 一个存储方法域。JVM 是运行在操作系统之上的&#xff0c;它与硬件没有直接的交互。 (2) 运行过程&#xff1a; 我们都…