实战项目 在线学院之集成springsecurity的配置以及执行流程
一 后端操作配置
1.0 工程结构

1.1 在common下创建spring_security模块

1.2 pom文件中依赖的注入

1.3 在service_acl模块服务中引入spring-security权限认证模块
1.3.1 service_acl引入spring-security

1.3.2 在service_acl编写查询数据库信息
定义userDetailServiceImpl 查询用户信息的实现类
1.4 springsecurity的配置文件
1.Spring Security的核心配置就是继承WebSecurityConfigurerAdapter并注解@EnableWebSecurity的配置。
这个配置指明了用户名密码的处理方式、请求路径的开合、登录登出控制等和安全相关的配置

2.配置一些放行的请求

3.代码
package com.atguigu.serurity.config;import com.atguigu.serurity.filter.TokenAuthenticationFilter;
import com.atguigu.serurity.filter.TokenLoginFilter;
import com.atguigu.serurity.security.DefaultPasswordEncoder;
import com.atguigu.serurity.security.TokenLogoutHandler;
import com.atguigu.serurity.security.TokenManager;
import com.atguigu.serurity.security.UnauthorizedEntryPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;/*** <p>* Security配置类* </p>** @author qy* @since 2019-11-18*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class TokenWebSecurityConfig extends WebSecurityConfigurerAdapter {private UserDetailsService userDetailsService;private TokenManager tokenManager;private DefaultPasswordEncoder defaultPasswordEncoder;private RedisTemplate redisTemplate;@Autowiredpublic TokenWebSecurityConfig(UserDetailsService userDetailsService, DefaultPasswordEncoder defaultPasswordEncoder,TokenManager tokenManager, RedisTemplate redisTemplate) {this.userDetailsService = userDetailsService;this.defaultPasswordEncoder = defaultPasswordEncoder;this.tokenManager = tokenManager;this.redisTemplate = redisTemplate;}/*** 配置设置* @param http* @throws Exception*/@Overrideprotected void configure(HttpSecurity http) throws Exception {http.exceptionHandling().authenticationEntryPoint(new UnauthorizedEntryPoint()).and().csrf().disable().authorizeRequests().anyRequest().authenticated().and().logout().logoutUrl("/admin/acl/index/logout").addLogoutHandler(new TokenLogoutHandler(tokenManager,redisTemplate)).and().addFilter(new TokenLoginFilter(authenticationManager(), tokenManager, redisTemplate)).addFilter(new TokenAuthenticationFilter(authenticationManager(), tokenManager, redisTemplate)).httpBasic();}/*** 密码处理* @param auth* @throws Exception*/@Overridepublic void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService).passwordEncoder(defaultPasswordEncoder);}/*** 配置哪些请求不拦截* @param web* @throws Exception*/@Overridepublic void configure(WebSecurity web) throws Exception {
// web.ignoring().antMatchers("/api/**",
// "/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**"
// );web.ignoring().antMatchers("/*/**");}
}
1.5 认证授权工具类
1.加密解密工具类
@Component
public class DefaultPasswordEncoder implements PasswordEncoder {public DefaultPasswordEncoder() {this(-1);}/*** @param strength* the log rounds to use, between 4 and 31*/public DefaultPasswordEncoder(int strength) {}public String encode(CharSequence rawPassword) {return MD5.encrypt(rawPassword.toString());}public boolean matches(CharSequence rawPassword, String encodedPassword) {return encodedPassword.equals(MD5.encrypt(rawPassword.toString()));}
}
2.token加密工具
@Component
public class TokenManager {private long tokenExpiration = 24*60*60*1000;private String tokenSignKey = "123456";public String createToken(String username) {String token = Jwts.builder().setSubject(username).setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)).signWith(SignatureAlgorithm.HS512, tokenSignKey).compressWith(CompressionCodecs.GZIP).compact();return token;}public String getUserFromToken(String token) {String user = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token).getBody().getSubject();return user;}public void removeToken(String token) {//jwttoken无需删除,客户端扔掉即可。}}
3.TokenLogoutHandler:退出实现
package com.atguigu.serurity.security;import com.atguigu.commonutils.R;
import com.atguigu.commonutils.ResponseUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutHandler;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** <p>* 登出业务逻辑类* </p>** @author qy* @since 2019-11-08*/
public class TokenLogoutHandler implements LogoutHandler {private TokenManager tokenManager;private RedisTemplate redisTemplate;public TokenLogoutHandler(TokenManager tokenManager, RedisTemplate redisTemplate) {this.tokenManager = tokenManager;this.redisTemplate = redisTemplate;}@Overridepublic void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {String token = request.getHeader("token");if (token != null) {tokenManager.removeToken(token);//清空当前用户缓存中的权限数据String userName = tokenManager.getUserFromToken(token);redisTemplate.delete(userName);}ResponseUtil.out(response, R.ok());}}
4.异常管理:未授权统一处理
public class UnauthorizedEntryPoint implements AuthenticationEntryPoint {@Overridepublic void commence(HttpServletRequest request, HttpServletResponse response,AuthenticationException authException) throws IOException, ServletException {ResponseUtil.out(response, R.error());}
}
1.6 创建认证授权实体类

1.user
@Data
@ApiModel(description = "用户实体类")
public class User implements Serializable {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "微信openid")private String username;@ApiModelProperty(value = "密码")private String password;@ApiModelProperty(value = "昵称")private String nickName;@ApiModelProperty(value = "用户头像")private String salt;@ApiModelProperty(value = "用户签名")private String token;}
2.securityUser
@Data
@Slf4j
public class SecurityUser implements UserDetails {//当前登录用户private transient User currentUserInfo;//当前权限private List<String> permissionValueList;public SecurityUser() {}public SecurityUser(User user) {if (user != null) {this.currentUserInfo = user;}}@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {Collection<GrantedAuthority> authorities = new ArrayList<>();for(String permissionValue : permissionValueList) {if(StringUtils.isEmpty(permissionValue)) continue;SimpleGrantedAuthority authority = new SimpleGrantedAuthority(permissionValue);authorities.add(authority);}return authorities;}@Overridepublic String getPassword() {return currentUserInfo.getPassword();}@Overridepublic String getUsername() {return currentUserInfo.getUsername();}@Overridepublic boolean isAccountNonExpired() {return true;}@Overridepublic boolean isAccountNonLocked() {return true;}@Overridepublic boolean isCredentialsNonExpired() {return true;}@Overridepublic boolean isEnabled() {return true;}
}
1.7 认证授权的过滤器
1.7.1 认证TokenLoginFilter:认证的filter

public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {private AuthenticationManager authenticationManager;private TokenManager tokenManager;private RedisTemplate redisTemplate;public TokenLoginFilter(AuthenticationManager authenticationManager, TokenManager tokenManager, RedisTemplate redisTemplate) {this.authenticationManager = authenticationManager;this.tokenManager = tokenManager;this.redisTemplate = redisTemplate;this.setPostOnly(false);this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/admin/acl/login","POST"));}@Overridepublic Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)throws AuthenticationException {try {User user = new ObjectMapper().readValue(req.getInputStream(), User.class);return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), new ArrayList<>()));} catch (IOException e) {throw new RuntimeException(e);}}/*** 登录成功* @param req* @param res* @param chain* @param auth* @throws IOException* @throws ServletException*/@Overrideprotected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain,Authentication auth) throws IOException, ServletException {SecurityUser user = (SecurityUser) auth.getPrincipal();String token = tokenManager.createToken(user.getCurrentUserInfo().getUsername());redisTemplate.opsForValue().set(user.getCurrentUserInfo().getUsername(), user.getPermissionValueList());ResponseUtil.out(res, R.ok().data("token", token));}/*** 登录失败* @param request* @param response* @param e* @throws IOException* @throws ServletException*/@Overrideprotected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,AuthenticationException e) throws IOException, ServletException {ResponseUtil.out(response, R.error());}
}
1.7.2 授权TokenAuthenticationFilter

package com.atguigu.serurity.filter;import com.atguigu.commonutils.R;
import com.atguigu.commonutils.ResponseUtil;
import com.atguigu.serurity.security.TokenManager;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.util.StringUtils;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;/*** <p>* 访问过滤器* </p>** @author qy* @since 2019-11-08*/
public class TokenAuthenticationFilter extends BasicAuthenticationFilter {private TokenManager tokenManager;private RedisTemplate redisTemplate;public TokenAuthenticationFilter(AuthenticationManager authManager, TokenManager tokenManager,RedisTemplate redisTemplate) {super(authManager);this.tokenManager = tokenManager;this.redisTemplate = redisTemplate;}@Overrideprotected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)throws IOException, ServletException {logger.info("================="+req.getRequestURI());if(req.getRequestURI().indexOf("admin") == -1) {chain.doFilter(req, res);return;}UsernamePasswordAuthenticationToken authentication = null;try {authentication = getAuthentication(req);} catch (Exception e) {ResponseUtil.out(res, R.error());}if (authentication != null) {SecurityContextHolder.getContext().setAuthentication(authentication);} else {ResponseUtil.out(res, R.error());}chain.doFilter(req, res);}private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {// token置于header里String token = request.getHeader("token");if (token != null && !"".equals(token.trim())) {String userName = tokenManager.getUserFromToken(token);List<String> permissionValueList = (List<String>) redisTemplate.opsForValue().get(userName);Collection<GrantedAuthority> authorities = new ArrayList<>();for(String permissionValue : permissionValueList) {if(StringUtils.isEmpty(permissionValue)) continue;SimpleGrantedAuthority authority = new SimpleGrantedAuthority(permissionValue);authorities.add(authority);}if (!StringUtils.isEmpty(userName)) {return new UsernamePasswordAuthenticationToken(userName, token, authorities);}return null;}return null;}
}
二 前端整合
2.1 element-ui的替换
将修改好的element-ui替换现在工程中的element-ui文件夹。先删除旧的,再复制新的element-ui文件夹内容。
2.2 其他文件替换
2.2.1 login.js替换和acl文件夹
将图中右边修改好的,acl文件目录和login.js复制到左边,进行替换。

login.js的内容

2.2.2 router的替换
右边写好的router.js替换左边的

router.js的内容

2.2.3 store的替换

2.3 安装依赖

2.4 需要修改的配置的地方
1.router.js:修改router文件夹里面index.js里面路径和vue文件地址

2. 修改数据库菜单表路径和页面地址

2.5 修改前端项目请求地址是网关地址
三 启动
3.1 前端启动
启动命令: npm run dev

3.2 后端启动
1.nacos 2.redis
3.acl服务,和网关服务

四 springsecurity执行流程*
4.1 步骤
4.1.1.输入用户名和密码

4.2.2.请求执行到TokenLoginFilter的attemptAuthentication方法
在这个方法中获取用户名和密码

4.3.3. 查询用户信息:跳转到userDetailServiceImpl的loadUserByUserName方法。
主要是通过用户名,查询用户信息和权限信息,封装到springsecurity对象中进行返回。

4.3.4.认证成功后,再次跳转到Tolenloginfilter类中的sucessfulAuthentication()方法,如果失败跳转到unsuccessfulAuthentication方法
获取返回对象;
根据对象里面用户名生成token;
把用户和权限信息放到redis
返回生成的token
4.3.5 请求到达授权过滤器
请求到达授权过滤器TokenAuthenticationFilter的getAuthentication方法。
从header中获取token信息,从token中获取用户名,根据用户名从redis中获取该用的权限信息。

相关文章:
实战项目 在线学院之集成springsecurity的配置以及执行流程
一 后端操作配置 1.0 工程结构 1.1 在common下创建spring_security模块 1.2 pom文件中依赖的注入 1.3 在service_acl模块服务中引入spring-security权限认证模块 1.3.1 service_acl引入spring-security 1.3.2 在service_acl编写查询数据库信息 定义userDetailServiceImpl 查…...
【ARM CoreLink CCI-400 控制器简介】
文章目录 CCI-400 介绍 CCI-400 介绍 CCI(Cache Coherent Interconnect)是ARM 中 的Cache一致性控制器。 CCI-400 将 Interconnect 和coherency 功能结合到一个模块中。它支持多达两个ACE master 点的interface,例如: Cortex-A…...
Linux xargs命令继续学习
之前学习过Linux xargs,对此非常的不熟悉,下面继续学习一下; xargs 可以将管道或标准输入(stdin)数据转换成命令行参数,也能够从文件的输出中读取数据; xargs也可以给命令传递参数;…...
【广州华锐互动】数字孪生智慧楼宇3D可视化系统:掌握实时运行状态,优化运营管理
在过去的几年中,科技的发展极大地改变了我们的生活和工作方式。其中,三维数据可视化技术的出现,为我们提供了全新的理解和观察世界的方式。特别是在建筑行业,数字孪生智慧楼宇3D可视化系统的出现,让我们有机会重新定义…...
20230904工作心得:集合应该如何优雅判空?
1 集合判空 List<String> newlist null;//空指针if( !newlist.isEmpty()){newlist.forEach(System.out::println);}//空指针if(newlist.size()>0 && newlist!null){newlist.forEach(System.out::println);}//可行if(newlist!null && newlist.size()&…...
使用Python进行健身手表数据分析
健身手表(Fitness Watch)数据分析涉及分析健身可穿戴设备或智能手表收集的数据,以深入了解用户的健康和活动模式。这些设备可以跟踪所走的步数、消耗的能量、步行速度等指标。本文将带您完成使用Python进行Fitness Watch数据分析的任务。 Fitness Watch数据分析是健…...
什么是malloxx勒索病毒,服务器中malloxx勒索病毒了怎么办?
Malloxx勒索病毒是一种新型的电脑病毒,它通过加密用户电脑中的重要文件数据来威胁用户,并以此勒索钱财。这种病毒并不是让用户的电脑瘫痪,而是以非常独特的方式进行攻击。在感染了Malloxx勒索病毒后,它会加密用户服务器中的数据&a…...
CocosCreator3.8研究笔记(六)CocosCreator 脚本装饰器的理解
一、什么是装饰器? 装饰器是TypeScript脚本语言中的概念。 TypeScript的解释:在一些场景下,我们需要额外的特性来支持标注或修改类及其成员。装饰器(Decorators)为我们在类的声明及成员上通过元编程语法添加标注提供了…...
docker login harbor http login登录
前言 搭建的 harbor 仓库为 http 协议,在本地登录时出现如下报错: docker login http://192.168.xx.xx Username: admin Password: Error response from daemon: Get "https://192.168.xx.xx/v2/": dialing 192.168.xx.xx:443 matches static …...
day5 qt
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);timer_idthis->startTimer(100);//啓動一個定時器 每100ms發送一次信號ui->Edit1->setPlaceholderTex…...
【80天学习完《深入理解计算机系统》】第十三天 3.7 缓冲区溢出 attack lab
3.7 缓冲区溢出 && attack lab...
Hadoop生态之hive
一 概述与特点 之所以把Hive放在Hadoop生态里面去写,是因为它本身依赖Hadoop。Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类 SQL 查询功能。 其本质是将 SQL 转换为 MapReduce/Spark 的任务进行运算,底层由 HDFS 来提供…...
AWS DynamoDB浅析
AWS DynamoDB是一个NOSQL数据库。 可以通过IAM直接控制权限,和AWS其他服务连用非常方便。 DynamoDB的几个概念 Partition Key:分区键。如果没有Sort key,那么Partition Key必须唯一,如有Sort key,Partition Key可以重…...
Linux安装ffmpeg
1 下载yasm wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz tar -zxvf yasm-1.3.0.tar.gz cd yasm-1.3.0 ./configure make && make install2 下载ffmpeg wget http://ffmpeg.org/releases/ffmpeg-3.1.3.tar.bz2 tar jxvf ffmpeg-3.1.3.tar.…...
(18)不重启服务动态停止、启动RabbitMQ消费者
我们在消费RabbitMQ消息的过程中,有时候可能会想先暂停消费一段时间,然后过段时间再启动消费者,这个需求怎么实现呢?我们可以借助RabbitListenerEndpointRegistry这个类来实现,它的全类名是org.springframework.amqp.r…...
数据仓库的流程
数据仓库完全用统计分析框架实现:Spark,MR 但是因为实际生产环境中,需求量非常大, 如果每个需求都采用独立c代码开发方式,重复计算会很多. 提高性能的方法: 1.减少数据量 2. 减少重复计算 例如RDD cache 可以减少重复计算,但是不安全,都在缓存中, persist 都放内存中,但是慢 而…...
MyBatis-Plus深入 —— 条件构造器与插件管理
前言 在前面的文章中,荔枝梳理了一个MyBatis-Plus的基本使用、配置和通用Service接口,我们发现在MyBatis-Plus的辅助增强下我们不再需要通过配置xml文件中的sql语句来实现基本的sql操作了,不愧是最佳搭档!在这篇文章中,…...
C语言结构体的初始化方式
逐个初始化字段:这是最直接的方式,你可以逐个为结构体的每个字段进行初始化。 struct Student { char name[50]; int age; float marks; }; struct Student student1 {"Alice", 20, 89.5}; 2.使用结构体字面值初始化:这种方…...
Vue生成多文件pdf准考证
这是渲染的数据 这是生成的pdf文件,直接可以打印 需要安装和npm依赖和引入封装的pdf.js文件 npm install --save html2canvas // 页面转图片 npm install jspdf --save // 图片转pdfpdf.js文件 import html2canvas from "html2canvas"; import jsPDF …...
Rust的derive思考
这几天在Yew的学习实践中,发现derive中的参数中包含了yew自己的东西,比如yew::Properties。习惯使用#[derive(Clone, Debug, PartialEq)]之后,发现还有新的成员,这让我好奇起来。 首先让我们来回顾一下derive是什么。 #[derive(…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
