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 {
    //加密
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();//新建密码加密器
    }

    @Override
    protected 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")//有两个权限
        ;
    }

    @Override
    protected 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 {
    @Autowired
    private UserDao userDao;
    @Autowired
    private PermissionDao permissionDao;
    @Override
    public 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 {
    @Autowired
    private MyUserDetailService myUserDetailService;
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }



    @Override
    protected 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")//

        ;

    }
    @Override
    protected 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();
    }
}

总结

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【python】深入探索使用Matplotlib中的plt.legend()添加图例

当我们绘制复杂的图表&#xff0c;尤其是包含多个数据系列的图表时&#xff0c;一个清晰、易读的图例是至关重要的。plt.legend()函数是Matplotlib库中用于添加和定制图例的关键工具。在本篇博文中&#xff0c;我们将深入探讨plt.legend()的功能、用法以及如何通过它提升图表的…

Tomcat线程池原理(上篇:初始化原理)

文章目录 前言正文一、从启动脚本开始分析二、ProtocolHandler 的启动原理三、AbstractEndPoint 的启动原理四、创建默认线程池五、参数配置原理5.1 常规的参数配置5.2 自定义线程池5.3 测试自定义线程 前言 在Java Web的开发过程中&#xff0c;Tomcat常用的web容器。SpringBo…

挑战杯 基于YOLO实现的口罩佩戴检测 - python opemcv 深度学习

文章目录 0 前言1 课题介绍2 算法原理2.1 算法简介2.2 网络架构 3 关键代码4 数据集4.1 安装4.2 打开4.3 选择yolo标注格式4.4 打标签4.5 保存 5 训练6 实现效果6.1 pyqt实现简单GUI6.3 视频识别效果6.4 摄像头实时识别 7 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xf…

泛微e-office系统存在敏感信息泄露 附POC软件

免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。 1. 泛微e-office系统简介 微信公众号搜索:南风漏洞复…

车载软件架构Adaptive AUTOSAR —— 身份和访问管理和加密技术

车载软件架构Adaptive AUTOSAR —— 身份和访问管理和加密技术 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。…

探索NFC技术在游戏玩具娱乐,医疗保健和穿戴设备领域的三大应用

NFC是与众不同的无线技术。这意味着它只能在两个设备相近时起作用。在其他用无线技术随机广播的方式以被接收时&#xff0c;NFC更重要的独特之处于其使用电源的方式。或者&#xff0c;更确切地说&#xff0c;它可以在不供电的环境下进行工作。它是一种非接触式智能卡技术的演进…

挑战30天学完Python:Day16 日期时间

&#x1f4d8; Day 16 &#x1f389; 本系列为Python基础学习&#xff0c;原稿来源于 30-Days-Of-Python 英文项目&#xff0c;大奇主要是对其本地化翻译、逐条验证和补充&#xff0c;想通过30天完成正儿八经的系统化实践。此系列适合零基础同学&#xff0c;或仅了解Python一点…

干货分享 | TSMaster 序列发送模块在汽车开发测试中的应用

众所周知&#xff0c;序列发送模块可以不需要脚本代码实现测试中特定控制报文序列的发送&#xff0c;该模块多用于循环顺序控制的测试案例中。序列发送模块的常用场景&#xff0c;主要是针对一些新开发的产品需要通过该模块来验证产品功能等等。本文重点和大家分享一下关于TSMa…

STM32—启用按键

​ 目录 1 、电路构成及原理图 2、编写实现代码 main.c main.h key.c 3、代码讲解 4、 烧录到开发板调试、验证代码 5、检验效果 本人使用的是朗峰 STM32F103 系列开发板&#xff0c;此笔记基于这款开发板记录。 1 、电路构成及原理图 重要&#xff01;一定先用短路…

ZFS存储池速度以及RAID说明

文章目录 前言1. STRIPED VDEV&#xff08;RAID 0&#xff09;性能示例&#xff1a; 2. MIRRORED VDEV &#xff08;RAID 1&#xff09;1x 12-way mirror:6x 2-way mirror:4x 3-way mirro&#xff1a;性能示例&#xff1a; 3. RAIDZ VDEVRAIDZ3:RAIDZ2&#xff08;RAID6&#x…

css实现梯形

<div class"trapezoid"></div> .trapezoid {width: 200px;height: 0;border-bottom: 100px solid red; /* 定义梯形的底边 */border-left: 50px solid transparent; /* 定义梯形的左边 */border-right: 50px solid transparent; /* 定义梯形的右边 */} …

【RN】开发第一个react-native程序

简言 React Native 是一个使用React和应用平台的原生功能来构建 Android 和 iOS 应用的开源框架。通过 React Native&#xff0c;您可以使用 JavaScript 来访问移动平台的 API&#xff0c;以及使用 React 组件来描述 UI 的外观和行为&#xff1a;一系列可重用、可嵌套的代码。…

代码随想录算法训练营第十九天|认识回溯,77.组合

认识回溯 77.组合 认识回溯 回溯法也可以叫做回溯搜索法&#xff0c;它是一种搜索的方式。 回溯是递归的副产品&#xff0c;只要有递归就会有回溯。 回溯法的效率 回溯的本质是穷举&#xff0c;即使加了剪枝操作&#xff0c;其本质也还是穷举 回溯法解决的问题 组合问题…

【2024软件测试面试必会技能】Jmeter_性能测试(4):性能测试脚本的优化

性能测试脚本的优化 以PHP论坛为例&#xff1a;http://47.107.178.45/phpwind/ 根据上一篇的性能测试(3&#xff09;的脚本进行优化&#xff1b;见下图&#xff1a; 如上图中&#xff0c;把发帖和回帖的事务添加到随机控制器中&#xff0c;登录操作添加到仅一次控制器中&…

Python学习笔记——自定义函数(传递任意数量的实参)

Python允许函数从调用语句中收集任意数量的实参。例如下面自定义函数制作一个披萨&#xff0c;它需要接受很多配料&#xff0c;但无法预先确定顾客要点多少种配料。 下面行数只有一个形参*toppings&#xff0c;不管调用语句提供多少个实参&#xff0c;这个参数都会收集到&…

阿里云/腾讯云幻兽帕鲁服务器为什么更新/重启之后,服务器存档没了?

有的朋友说&#xff0c;他的阿里云幻兽帕鲁服务器重启了一下后&#xff0c;服务器存档就没了&#xff1f;这是怎么回事呢&#xff0c;其实可能的原因&#xff0c;一是服务器还有重启完成&#xff0c;也就是游戏服务端还没有启动&#xff0c;就登进去&#xff0c;可能会显示网络…

智慧公厕是什么?智慧公厕对智慧城市的意义

城市的信息化发展需要催化了智慧城市&#xff0c;公共厕所作为城市的重要民生设施&#xff0c;如何实现更高阶的信息化建设&#xff0c;成为一个重要课题。那么&#xff0c;智慧公厕是什么&#xff1f;为什么它对智慧城市的建设如此重要&#xff1f;本文以智慧公厕源头厂家广州…

git工具

一、命令行工具 二、Git 客户端可视化工具-推荐 1.常用工具 tortoisegit 官网 https://tortoisegit.org/ 推荐 sourcetree 官网https://www.sourcetreeapp.com/ 2.tortoisegit安装 2.1 下载安装包 2.2 下载语言包 2.3 安装 2.4 安装语言包 5.使用 5.1 新建分支 5.2 切换分支…

力扣精选算法100道——Z字形变换(模拟专题)

目录 &#x1f388;了解题意 &#x1f388;算法原理 &#x1f6a9;先处理第一行和最后一行 &#x1f6a9;再处理中间行 &#x1f388;实现代码 &#x1f388;了解题意 大家看到这个题目的时候肯定是很迷茫的&#xff0c;包括我自己也是搞不清楚题目什么意思&#xff0c;我…

R cox回归 ggDCA报错

临床预测模型的决策曲线分析&#xff08;DCA&#xff09;&#xff1a;基于ggDCA包 决策曲线分析法&#xff08;decision curve analysis&#xff0c;DCA&#xff09;是一种评估临床预测模型、诊断试验和分子标记物的简单方法。 我们在传统的诊断试验指标如&#xff1a;敏感性&a…