SpringSecurity安全框架

我们使用这个springSecurity安全框架,作用是认证,授权,将用户的权限和对应的资源进行绑定,默认的是在内存中保存的,实际开发中,是需要根据项目业务的需求对某些方法进行重写,使数据库中权限对应的资源进行绑定,就是查看当前登录的用户所扮演的角色,该角色有哪些权限

授权

1内存交互资源绑定

这是框架默认的绑定方式,根据业务需求可以重写某些方法,连接数据库,进行交互进行资源绑定

inMemoryAuthentication

1创建一个SpringBoot项目

2配置类MySecurityConfig

package com.aaa.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {//加密@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();//新建密码加密器}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {//内存交互auth.inMemoryAuthentication().withUser("zhangsan").password(passwordEncoder().encode("123456")).roles("admin").authorities("user:query", "user:delete", "user:update", "user:insert")//手动设置的用户权限绑定资源,有4个权限.and().withUser("lisi").password(passwordEncoder().encode("123456")).roles("test").authorities("user:query", "user:export")//有两个权限;}@Overrideprotected void configure(HttpSecurity http) throws Exception {//登录前http.formLogin().loginPage("/login.html").loginProcessingUrl("/mylogin").successForwardUrl("/success").failureUrl("/fail.html") // 直接指向一个HTML页面.permitAll();//登录后http.exceptionHandling().accessDeniedPage("/403.html");//禁止2跨域伪造请求的验证http.csrf().disable();http.authorizeRequests().anyRequest().authenticated();}
}

 3添加注解

@EnableGlobalMethodSecurity(prePostEnabled = true)//开启安全框架注解

4在controller层加注解

在对应的方法上加注解

@PreAuthorize(value="hasAnyAuthority('user:query')")

package com.aaa.controller;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyUserController {@GetMapping("query")@PreAuthorize(value="hasAnyAuthority('user:query')")public String query(){System.out.println("访问查询资源");return "查询资源";}@GetMapping("delete")@PreAuthorize(value = "hasAuthority('user:delete')")public String delete(){System.out.println("访问删除资源");return "删除资源";}@GetMapping("update")@PreAuthorize(value = "hasAuthority('user:update')")public String update(){System.out.println("访问修改资源");return "修改资源";}@GetMapping("insert")@PreAuthorize(value = "hasAuthority('user:insert')")public String insert(){System.out.println("访问添加资源");return "添加资源";}@GetMapping("export")@PreAuthorize(value = "hasAuthority('user:export')")public String export(){System.out.println("访问导出资源");return "导出资源";}
}

2与数据库交互进行权限的资源绑定

1添加依赖

<!--添加依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId><version>2.6.13</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.4</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.26</version></dependency>

2写属性文件

加载资源文件

3创建dao层和entity(实体类)

举一个接口和一个实体类例子

user-role-permission,

从用户表到角色表,再到权限表

sys_user--->sys_user_role--->sys_role_permission--->sys_permission

mybatis-plus先根据条件(用户的名)从用户表sys_user筛选,获取用户id,

然后拿着用户的id从用户角色表sys_user_role获取到用户所对应的roleid,

接着拿着roleid从角色权限表sys_role_permission获取permissionid,

再拿着权限id,(permissionid)到权限表sys_permission里获取所有全部权限信息,

最后绑定到用户上

sql语句

select DISTINCT sys_permission.* from sys_permission
join sys_role_permission 
on sys_permission.perid=sys_role_permission.perid
join sys_user_role 
on sys_role_permission.roleid=sys_user_role.roleid
where sys_user_role.userid=#{userid}

4 写自己的业务层

根据业务需求,重写框架的某些默认方法,进行权限绑定

package com.aaa.service;import com.aaa.dao.PermissionDao;
import com.aaa.dao.UserDao;
import com.aaa.entity.Permission;
import com.aaa.entity.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.Collection;
import java.util.List;@Service
public class MyUserDetailService implements UserDetailsService {@Autowiredprivate UserDao userDao;@Autowiredprivate PermissionDao permissionDao;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//完成根据账户查询数据库即可QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("username",username);User user = userDao.selectOne(queryWrapper);if(user!=null){//permissions集合,源类型的集合,源集合--->目标类型的集合转换List<Permission> permissions = permissionDao.selectByUserId(user.getUserid());//空的SimpleGrantedAuthority类型的数组,目标类型的集合Collection<SimpleGrantedAuthority> authorities= new ArrayList<>();for (Permission per:permissions) {//把permissions集合里的东西拿出来,放到空集合里SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(per.getPercode());authorities.add(simpleGrantedAuthority);}org.springframework.security.core.userdetails.User userDetail =new org.springframework.security.core.userdetails.User(user.getUsername(),user.getUserpwd(),authorities);return userDetail;}return null;}}

5再配置类MySecurityConfig

用自己写的业务替换掉框架给的

package com.aaa.config;
import com.aaa.service.MyUserDetailService;
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.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate MyUserDetailService myUserDetailService;@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {//数据库交互auth.userDetailsService(myUserDetailService);//内存交互
//        auth.inMemoryAuthentication()
//                .withUser("zhangsan")
//                .password(passwordEncoder().encode("123456"))
//                .roles("admin")
//                .authorities("user:query","user:delete","user:update","user:insert")
//                .and()
//                .withUser("lisi")
//                .password(passwordEncoder().encode("123456"))
//                .roles("test")
//                .authorities("user:query","user:export")//;}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.formLogin().loginPage("/login.html").loginProcessingUrl("/mylogin").successForwardUrl("/success").failureUrl("/fail.html") // 直接指向一个HTML页面.permitAll();
//        http.authorizeRequests()
//                .antMatchers("/query").hasAnyAuthority("user:query")
//                .antMatchers("/delete").hasAnyAuthority("user:delete")
//                .antMatchers("/update").hasAnyAuthority("user:update")
//                .antMatchers("/insert").hasAnyAuthority("user:insert")
//                .antMatchers("/export").hasAnyAuthority("user:export");http.exceptionHandling().accessDeniedPage("/403.html");//禁止2跨域伪造请求的验证http.csrf().disable();http.authorizeRequests().anyRequest().authenticated();}
}

总结

根据业务需求调用自己的业务层(自己写的),去代替框架的部门业务实现需求

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

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

相关文章

【操作系统】

计算机操作系统 计算机是如何让用户得到好的体验什么是操作系统&#xff08;OS&#xff09;操作系统如何管理 计算机是如何让用户得到好的体验 计算机系统是由计算机硬件和软件组成的。用户使用计算机&#xff0c;比如在文本文件填写内容&#xff0c;通过邮箱发送邮件&#xf…

Aloudata StarRocks 直播预告:指标平台的物化加速实践

数据指标的管理、研发和应用一直存在着诸多痛点&#xff0c;这些挑战促使了对指标平台解决方案的需求不断增长。2月29日&#xff08;星期四&#xff09;19:00&#xff0c;Aloudata 将与 StarRocks 携手举办线上直播&#xff0c;深入揭秘第三代指标平台物化加速的强大能力&#…

大蟒蛇(Python)笔记(总结,摘要,概括)——第10章 文件和异常

目录 10.1 读取文件 10.1.1 读取文件的全部内容 10.1.2 相对文件路径和绝对文件路径 10.1.3 访问文件中的各行 10.1.4 使用文件的内容 10.1.5 包含100万位的大型文件 10.1.6 圆周率中包含你的生日吗 10.2 写入文件 10.2.1 写入一行 10.2.2 写入多行 10.3 异常 10.3.1 处理Ze…

基于springboot+vue的课程答疑系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

外站群服务器的特性及使用优势

随着互联网的快速发展&#xff0c;站群服务器在网站运营中扮演着越来越重要的角色。相较于国内站群服务器&#xff0c;国外站群服务器因其独特的特性和使用优势&#xff0c;受到了众多网站管理员的青睐。本文将对国外站群服务器的特性及使用优势进行科普介绍。 一、国外站群服务…

【Spring Cloud】实现微服务调用的负载均衡

文章目录 什么是负载均衡自定义实现负载均衡启动shop-product微服务通过nacos查看微服务的启动情况自定义实现负载均衡 基于Ribbon实现负载均衡添加注解修改服务调用的方法Ribbon支持的负载均衡策略通过修改配置来调整 Ribbon 的负载均衡策略通过注入Bean来调整 Ribbon 的负载均…

JS进阶——解构赋值

数组解构 基本&#xff1a; let [a, b, c] [1, 2, 3]; // a 1 // b 2 // c 3 可嵌套 let [a, [[b], c]] [1, [[2], 3]]; // a 1 // b 2 // c 3 可忽略 let [a, , b] [1, 2, 3]; // a 1 // b 3 不完全解构 let [a 1, b] []; // a 1, b undefined 剩余运…

如何创造价值写给自己的笔记

人工智能统领全文 在深入探讨这篇概述之前&#xff0c;我们首先需要理解一个核心观点&#xff1a;生产力的进步与生产关系的变革是相辅相成的。这一点在历史的长河中不断得到验证&#xff0c;从工业时代到信息时代&#xff0c;再到如今由人工智能引领的新时代&#xff0c;每一…

探索D咖智能饮品机器人的工作原理:科技、材料与设计的相互融合

智能饮品机器人是近年来随着人工智能和自动化技术的发展而崭露头角的一种创新产品。它将科技、材料和设计相互融合&#xff0c;为消费者带来了全新的饮品体验。下面D咖来探索智能饮品机器人的工作原理&#xff0c;以及科技、材料和设计在其中的作用。 首先&#xff0c;智能饮品…

Observability:使用 OpenTelemetry 和 Elastic 监控 OpenAI API 和 GPT 模型

作者&#xff1a; 来自 Elastic David Hope ChatGPT 现在非常火爆&#xff0c;甚至席卷了整个互联网。 作为 ChatGPT 的狂热用户和 ChatGPT 应用程序的开发人员&#xff0c;我对这项技术的可能性感到非常兴奋。 我看到的情况是&#xff0c;基于 ChatGPT 的解决方案将会呈指数级…

Docker本地部署Rss订阅工具并实现公网远程访问

文章目录 1. Docker 安装2. Docker 部署Rsshub3. 本地访问Rsshub4. Linux安装Cpolar5. 配置公网地址6. 远程访问Rsshub7. 固定Cpolar公网地址8. 固定地址访问 Rsshub是一个开源、简单易用、易于扩展的RSS生成器&#xff0c;它可以为各种内容生成RSS订阅源。 Rsshub借助于开源社…

如何在OpenWRT安装内网穿透工具实现远程访问本地搭建的web网站界面

文章目录 前言1. 检查uhttpd安装2. 部署web站点3. 安装cpolar内网穿透4. 配置远程访问地址5. 配置固定远程地址 前言 uhttpd 是 OpenWrt/LuCI 开发者从零开始编写的 Web 服务器&#xff0c;目的是成为优秀稳定的、适合嵌入式设备的轻量级任务的 HTTP 服务器&#xff0c;并且和…

【k近邻】Kd树构造与最近邻搜索示例

【k近邻】 K-Nearest Neighbors算法原理及流程 【k近邻】 K-Nearest Neighbors算法距离度量选择与数据维度归一化 【k近邻】 K-Nearest Neighbors算法k值的选择 【k近邻】 Kd树的构造与最近邻搜索算法 【k近邻】 Kd树构造与最近邻搜索示例 近邻法的实现需要考虑如何快速搜索个最…

第5讲:数组

第5讲:数组 1. 数组的概念2. 一维数组的创建和初始化2.1 数组创建2.2 数组的初始化2.3 数组的类型 3. ⼀维数组的使用3.1 数组下标3.2 数组元素的打印3.3 数组的输入 4. ⼀维数组在内存中的存储5. sizeof计算数组元素个数6. 二维数组的创建6.1 二维数组的概念6.2 二维数组的创建…

npm i卡在 idealTree buildDeps没反应的解决方案

通过git clone拉下项目后&#xff0c;进行项目的初始化下包时&#xff0c;发现npm i 并没有反应&#xff08;如图&#xff09;&#xff1a; 关键点&#xff1a;IdealTree 1.网络问题 确保你的网络连接正常&#xff0c;能够正常访问 npm 仓库。有时网络问题可能导致包无法正确…

游戏同步+游戏中的网络模块

原文链接&#xff1a;游戏开发入门&#xff08;九&#xff09;游戏同步技术_游戏数据同步机制流程怎么开发-CSDN博客 游戏开发入门&#xff08;十&#xff09;游戏中的网络模块_游戏开发组网-CSDN博客 3.同步技术的基本常识&#xff1a; a.同步给谁&#xff1f;某个用户&…

骨传导蓝牙耳机哪个好?六大精选购买技巧与规避常见陷阱指南

随着无线技术的飞速进步&#xff0c;蓝牙耳机已穿插在我们日常生活的每一处&#xff0c;成为常用的无线设备之一。而骨传导蓝牙耳机这一新科技产物近年来崭露头角。采用骨传导技术的耳机能通过头骨直接将声音传送至内耳&#xff0c;激活听觉神经&#xff0c;让声音直达听觉中枢…

http和https的区别(简述)

HTTP&#xff08;HyperText Transfer Protocol&#xff09;和HTTPS&#xff08;HTTP Secure&#xff09;都是用于在客户端和服务器之间传输数据的协议&#xff0c;但它们在安全性方面有重要的区别。 1.HTTP: 概述&#xff1a; HTTP是一种用于传输超文本的协议&#xff08;超文…

opencv从视频文件读取视频内容,从摄像头读取保存视频内容

文章目录 一、argparse模块1. 定义2. 讲解 二、读取、处理、保存图片1.读取图片2.灰度处理3.保存图片 三、读取摄像头、视频文件1.从摄像头读取2.从视频文件读取视频内容3.保存从摄像头读取的视频 一、argparse模块 1. 定义 &#xff08;1&#xff09;argparse模块使编写用户…

S-35390A计时芯片介绍及开发方案

计时芯片 S-35390A芯片是计时芯片&#xff0c;一般用来计算时间。低功耗&#xff0c;宽电压&#xff0c;受温度影响小&#xff0c;适用于很多电路。它有一个问题&#xff0c;不阻止用户设置不存在的时间&#xff0c;设置进去之后计时或者闹钟定时会出错。 规格书阅读 首先我…