Spring Security- 基于角色的访问控制

基于角色 或权限 进行访问控制

hasAuthority方法

如果当前的主体具有指定的权限,则返回true,否则返回false

修改配置类
  //当前登录用户 只有具备admins权限才可以访问这个路径
 .antMatchers("/test/index").hasAuthority("admins")

代码如下:

 package com.config;
 ​
 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 SecurityConfig extends WebSecurityConfigurerAdapter {
 ​
     @Autowired
     UserDetailsService userDetailsService;
 ​
 ​
     @Override
     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
     }
     @Bean
     PasswordEncoder passwordEncoder(){
         return new BCryptPasswordEncoder();
     }
 ​
     @Override
     protected void configure(HttpSecurity http) throws Exception {
         http.formLogin().loginPage("/login.html")   // 自定义登录页面
                         .loginProcessingUrl("/user/login")     //登录访问路径
                         .defaultSuccessUrl("/test/index").permitAll()      //登录成功后 跳转路径
                         .and().authorizeRequests()
                         .antMatchers("/","/user/login","/test/add").permitAll() //设置哪些路径可以不认证 直接访问
                          //当前登录用户 只有具备admins权限才可以访问这个路径
                         .antMatchers("/test/index").hasAuthority("admins")
                         .and().csrf().disable() ; // 关闭csrf的防护
     }
 }
修改 UserDetailsService, 把 返回的对象 设置权限

代码如下:

 
package com.service;
 ​
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.entity.UserInfo;
 import com.mapper.UserInfoMapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.AuthorityUtils;
 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.core.userdetails.UsernameNotFoundException;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.stereotype.Service;
 ​
 import java.util.ArrayList;
 import java.util.List;
 ​
 @Service("userDetailsService")
 public class MyUserDetailsService implements UserDetailsService {
 ​
     @Autowired
     private UserInfoMapper userInfoMapper;
 ​
 ​
 ​
     @Override
     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
 ​
         //根据用户名 查询
         QueryWrapper<UserInfo> wrapper=new QueryWrapper<>();
         wrapper.eq("name",username);   //查询 name列 的值 为 username的 数据
         UserInfo info = userInfoMapper.selectOne(wrapper);
         //判断
         if(info==null){   //没有用户 验证失败
             throw new UsernameNotFoundException("用户名不存在");
         }
 ​
         List<GrantedAuthority> list = AuthorityUtils.commaSeparatedStringToAuthorityList("admins");  //这里与配置类一致
         //返回数据库的用户名及密码
         return new User(info.getName(), new BCryptPasswordEncoder().encode(info.getPwd()),list);
     }
 }

启动测试: 输入正确的用户名及密码, 当前返回的用户 具有admins 权限, 因此可以看到 hello index

接下来 将 上面UserDetailsService的 权限 由 admins改为其他 , 还是输入 正确的用户名及密码则There was an unexpected error (type=Forbidden, status=403).

hasAnyAuthority方法

如果当前的主体由任何提供的角色的话 返回true

修改配置类

具备 admins 或 abc 的 都可以 访问 /test/index

修改UserDetailsService

启动测试:

输入正确的用户名及密码 : 看到 hello index

hasRole

如果用户具备给定角色就允许访问 否则出现403

如果当前主体具有指定的角色则返回true

修改配置类

 package com.config;
 ​
 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 SecurityConfig extends WebSecurityConfigurerAdapter {
 ​
     @Autowired
     UserDetailsService userDetailsService;
 ​
 ​
     @Override
     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
     }
     @Bean
     PasswordEncoder passwordEncoder(){
         return new BCryptPasswordEncoder();
     }
 ​
     @Override
     protected void configure(HttpSecurity http) throws Exception {
         http.formLogin().loginPage("/login.html")   // 自定义登录页面
                         .loginProcessingUrl("/user/login")     //登录访问路径
                         .defaultSuccessUrl("/test/index").permitAll()      //登录成功后 跳转路径
                         .and().authorizeRequests()
                 //       /user/login","/test/add" 面允许任意访问
                         .antMatchers("/","/user/login","/test/add").permitAll() //设置哪些路径可以不认证 直接访问
                          //当前登录用户 只有具备admins权限才可以访问这个路径
                         //.antMatchers("/test/index").hasAnyAuthority("admins","abc")
                         .antMatchers("/test/index").hasRole("sale")
                         .anyRequest().permitAll()
                         .and().csrf().disable() ; // 关闭csrf的防护
     }
 }
修改UserDetailsService

注意 配置类 写 sale , 这里需要增加前缀 ROLE_

 List<GrantedAuthority> list = AuthorityUtils.commaSeparatedStringToAuthorityList("admins,ROLE_sale");

启动 访问 输入正确 用户名 /密码 看到 hello index

hasAnyRole

表示用户具备任何一个条件都可以访问

修改配置类
 .antMatchers("/test/index").hasAnyRole("sale","p2")
修改UserDetailsService
 List<GrantedAuthority> list = AuthorityUtils.commaSeparatedStringToAuthorityList("admins,ROLE_p2");

启动访问 ,输入正确用户名/密码 可以看到 页面 hello index

自定义403页面

在static 下 建立 403.html

 <h1>未授权</h1>

在配置类进行配置:

 //配置没有权限访问跳转的页面
 http.exceptionHandling().accessDeniedPage("/403.html");

完整代码

 package com.config;
 ​
 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 SecurityConfig extends WebSecurityConfigurerAdapter {
 ​
     @Autowired
     UserDetailsService userDetailsService;
 ​
 ​
     @Override
     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
     }
     @Bean
     PasswordEncoder passwordEncoder(){
         return new BCryptPasswordEncoder();
     }
 ​
     @Override
     protected void configure(HttpSecurity http) throws Exception {
 ​
         //配置没有权限访问跳转的页面
         http.exceptionHandling().accessDeniedPage("/403.html");
 ​
         http.formLogin().loginPage("/login.html")   // 自定义登录页面
                         .loginProcessingUrl("/user/login")     //登录访问路径
                         .defaultSuccessUrl("/test/index").permitAll()      //登录成功后 跳转路径
                         .and().authorizeRequests()
                 //       /user/login","/test/add" 面允许任意访问
                         .antMatchers("/","/user/login","/test/add").permitAll() //设置哪些路径可以不认证 直接访问
                          //当前登录用户 只有具备admins权限才可以访问这个路径
                         //.antMatchers("/test/index").hasAnyAuthority("admins","abc")
                         //.antMatchers("/test/index").hasRole("sale")
                         .antMatchers("/test/index").hasAnyRole("sale","p2")
                         .anyRequest().permitAll()
                         .and().csrf().disable() ; // 关闭csrf的防护
     }
 }

修改 代码 让 其 没有权限 ,输入正确的用户名与密码

4注解方式

@secured

判断是否具有角色,另外需要注意的是这里匹配的字符串需要添加前缀 “ROLE"

使用注解先要开启注解功能!,

@EnableGlobalMethodSecurity(securedEnabled=true)

修改启动类或配置类 开启注解

选择 启动类

 @SpringBootApplication
 @MapperScan(basePackages = "com.mapper")
 @EnableGlobalMethodSecurity(securedEnabled = true)
 public class SSApp {
     public static void main(String[] args) {
         SpringApplication.run(SSApp.class,args);
     }
 }

在controller 方法上 使用注解 ,设置 角色

 
package com.controller;
 ​
 import org.springframework.security.access.annotation.Secured;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 ​
 @RestController
 @RequestMapping("/test")
 public class TestController {
 ​
     @GetMapping("/index")
     public String index(){
         return "hello index";
     }
 ​
 ​
     @GetMapping("/add")
     public String add(){
         return "hello security";
     }
 ​
 ​
 ​
     @GetMapping("/update") 
     @Secured({"ROLE_sale","ROLE_manager"})    ---- 注解访问 ,需要在启动类 开启注解  ,注意前缀
     public String update(){
         return "hello update";
     }
 ​
 ​
 }

在UserDetailsService 中 配置角色

 List<GrantedAuthority> list = AuthorityUtils.commaSeparatedStringToAuthorityList("admins,ROLE_sale");

启动 测试: 地址栏 输入 localhost:8080/test/update

然后输入 正确的用户名/密码 , 然后看到页面

@PreAuthorize

先开启注解功能

@EnableGlobalMethodSecurity(prePostEnabled = true)

@PreAuthorize:注解适合进入方法前的权限验证

@PreAuthorize可以将登录用户的roles/permissions参数传到方法中。。

使用方式:

在启动类开启注解

 @SpringBootApplication
 @MapperScan(basePackages = "com.mapper")
 @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled=true)
 public class SSApp {
     public static void main(String[] args) {
         SpringApplication.run(SSApp.class,args);
     }
 }

在controller方法上添加注解

 @GetMapping("/update")
 //@Secured({"ROLE_sale","ROLE_manager"})
 @PreAuthorize("hasAnyAuthority('admins','abc')")
 public String update(){
     return "hello update";
 }

在UserDetailsService 中 配置角色或权限

 List<GrantedAuthority> list = AuthorityUtils.commaSeparatedStringToAuthorityList("admins,ROLE_sale");

启动测试:

@PostAuthorize

先开启注解功能

@EnableGlobalMethodSecurity(prePostEnabled = true)

@PostAuthorize 注解使用并不多, 在方法执行后进行权限验证,适合验证带有返回值的权限

开启注解

 
@SpringBootApplication
 @MapperScan(basePackages = "com.mapper")
 @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled=true)
 public class SSApp {
     public static void main(String[] args) {
         SpringApplication.run(SSApp.class,args);
     }
 }

编写controller , 判断是否 具备 'admins','ROLE_abc'

 @GetMapping("/update")
 //@Secured({"ROLE_sale","ROLE_manager"})
 //@PreAuthorize("hasAnyAuthority('admins','abc')")
 @PostAuthorize("hasAnyAuthority('admins','abc')")
 public String update(){
     System.out.println("update.......");
     return "hello update";
 }

修改UserDetailsService , 让其拥有 admin 与 上面的 admins 不同

 List<GrantedAuthority> list = AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_sale");

启动测试 ,输入正确的用户名及密码 , 发现 具备admin 但没有 admins 权限, 控制台会打印 update.... ,然后显示 跳转到未授权页面403.html

@PostFilter 对返回数据做过滤

@PostFilter:权限验证之后对数据进行过滤,留下用户名是admin1的数据.

表达式中的 filterObject 引用的是方法返回值List中的某一个元素-

@PreFilter 对传入参数做过滤

@PreFilter 进入控制器之前对数据进行过滤

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

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

相关文章

达芬奇调色软件DaVinci Resolve Studio 18 中文激活版

DaVinci Resolve Studio 18是一款功能强大的视频编辑软件&#xff0c;它可以帮助用户轻松完成视频剪辑、调色、音频处理和特效合成等任务。 软件下载&#xff1a;DaVinci Resolve Studio 18 中文激活版下载 这款软件具有友好的用户界面和易于使用的功能&#xff0c;使得用户能够…

云服务器CVM_云主机_云计算服务器_弹性云服务器

腾讯云服务器CVM提供安全可靠的弹性计算服务&#xff0c;腾讯云明星级云服务器&#xff0c;弹性计算实时扩展或缩减计算资源&#xff0c;支持包年包月、按量计费和竞价实例计费模式&#xff0c;CVM提供多种CPU、内存、硬盘和带宽可以灵活调整的实例规格&#xff0c;提供9个9的数…

如何安装“MySQL在虚拟机ubuntu”win10系统?

1、 更新列表 sudo apt-get update 2、 安装MySQL服务器 sudo apt-get install mysql-server 3、 安装MySQL客户端 sudo apt-get install mysql-client 4、 配置MySQL sudo mysql_secure_installation 5、 测试MySQL systemctl status mysql.service MySQL数据库基本…

transbigdata笔记:轨迹停止点和行程提取

1 traj_stay_move——标识停靠点和行程 1.1 方法介绍 如果两个连续轨迹数据点&#xff08;栅格化处理之后&#xff09;之间的持续时间超过设定的阈值&#xff0c;将其视为停靠点。两个停靠点之间的时间段被视为一个行程 1.2 使用方法 transbigdata.traj_stay_move(data, pa…

从零开始搭建ubuntu 16.04 pwndocker环境

1.安装VMware-tools 1.1遇到问题 在使用 VMware Workstation时遇到了VMware Tools不能安装的问题&#xff0c;具体表现为&#xff1a;在要安装VMware Tools的虚拟机上右键 ----》安装VMware Tools(T)… 为灰色&#xff0c;不能够点击。 1.2解决方案    1. 关闭虚拟机&…

设计Twitter时间线和搜索功能

设计Twitter时间线和搜索功能 设计 facebook feed 和 设计 facebook search是相同的问题 第一步&#xff1a;定义用例和约束 定义问题的需求和范围&#xff0c;询问问题去声明用例和约束&#xff0c;讨论假设 ps: 没有一个面试官会展示详细的问题&#xff0c;我们需要定义一些用…

【软件测试】学习笔记-测试基础架构

这篇文章探讨什么是测试基础架构。 什么是测试基础架构&#xff1f; 测试基础架构指的是&#xff0c;执行测试的过程中用到的所有基础硬件设施以及相关的软件设施。因此&#xff0c;我们也把测试基础架构称之为广义的测试执行环境。通常来讲&#xff0c;测试基础 架构主要包括…

Leetcode23-数组能形成多少数对(2341)

1、题目 给你一个下标从 0 开始的整数数组 nums 。在一步操作中&#xff0c;你可以执行以下步骤&#xff1a; 从 nums 选出 两个 相等的 整数 从 nums 中移除这两个整数&#xff0c;形成一个 数对 请你在 nums 上多次执行此操作直到无法继续执行。 返回一个下标从 0 开始、长…

Spring Security-用户注销及记住我

用户注销 在配置类增加退出映射地址 Overrideprotected void configure(HttpSecurity http) throws Exception {//退出/注销http.logout().logoutUrl("/logout").logoutSuccessUrl("/test/hello").permitAll();} 完整代码: package com.config;​import o…

礼贺新春,徐坊大曲新品【中国红】

梁山徐坊大曲新推出中国风礼盒&#xff0c;以中国红为主题&#xff0c;为即将到来的新春佳节增添了浓厚的节日气氛。为您呈现一场视觉与味觉的盛宴。从礼盒的颜色到图案设计&#xff0c;无不体现出中国红的热情与活力&#xff0c;象征着吉祥、喜庆与团圆。梁山徐坊大曲&#xf…

设计模式之依赖倒转原则

在软件开发的世界里&#xff0c;设计模式一直是提升代码质量、确保软件稳定性以及优化软件可维护性的重要工具。而在这其中&#xff0c;依赖倒转原则无疑是其中最具代表性的设计模式之一。那么&#xff0c;什么是依赖倒转原则&#xff1f;它又为何如此重要&#xff1f;让我们一…

Android 系统启动过程纪要(基于Android 10)

前言 看过源码的都知道&#xff0c;Launcher系统启动都会经过这三个进程 init ->zygote -> system_server。今天我们就来讲解一下这三个进程以及Launcher系统启动。 init进程 准备Android虚拟机环境&#xff1a;创建和挂载系统文件目录&#xff1b;初始化属性服务&…

解决哈希冲突的几种方法

什么是hash冲突 哈希函数是一个映像&#xff0c;把任意长度的输入&#xff0c;通过Hash算法变换成固定长度的输出&#xff0c;这个输出就是Hash值&#xff1b; 当两个不同的输入&#xff0c;产生了同一个输出值即为哈希冲突 解决方式 开放定址法 开放寻址法的核心思想是&am…

PyQt5多线程使用

PyQt5多线程使用 本案例使用PyQt5多线程实现一个UI界面同时显示3个时间实时更新控件&#xff0c;从而直观地了解到Qt多线程是如何进行工作的。 from PyQt5.QtCore import QThread,pyqtSignal,QDateTime from PyQt5.QtWidgets import QApplication,QDialog,QLineEdit,QVBoxLay…

[Android]实现一个权限申请类

[Android]实现一个权限申请类 导言 在引入了动态权限申请之后&#xff0c;Android的权限申请就变得尤为繁琐&#xff0c;若是按照原有的方法一板一眼地进行申请&#xff0c;样板代码未免太多。因此本篇文章就使用ActivityResult API&#xff0c;来实现一个简单的权限申请类来帮…

【漏洞复现】Kubernetes PPROF内存泄漏漏洞(CVE-2019-11248)

Nx01 产品简介 Kubernetes&#xff08;简称K8S&#xff09;是Google在2014年开源的一个容器集群管理系统。它用于容器化应用程序的部署、扩展和管理&#xff0c;目标是让部署容器化应用简单且高效。 Nx02 漏洞描述 漏洞存在于Kubernetes的1.18.6版本之前&#xff0c;可能导致未…

「解析」Jetson配置 git服务

这两天感冒了在家休养&#xff0c;想着把之前买的 Jetson 开发板用起来&#xff0c;买Jetson的初衷就是用来学习Linux系统&#xff0c;顺道可以部署算法&#xff0c;以及一些其他需求&#xff0c;相比树莓派而言&#xff0c;Jetson开发相对更贵&#xff0c;但是其配备了英伟达的…

conda 安装, 配置以及使用

文章目录 1. 安装2. 配置2.1 如何配置2.2 快速设置取消自动进入 base 环境conda 添加清华源pip 添加清华源pip 更新为最新版本 3. 使用 conda 是 python 的环境管理工具包&#xff0c;非常好用&#xff0c;特别是 miniconda 相对于 conda 不需要安装其他的工具&#xff0c;而且…

详细讲解Python中的aioschedule定时任务操作

目录 前言1. 基本概念2. 基本API3. Demo 前言 如果下面的函数库无法执行&#xff0c;出现类似&#xff1a;&#xff08;前提是python3.7以上&#xff09; AttributeError: module ‘asyncio‘ has no attribute ‘run‘请检查run是否可跳转&#xff0c;如果无法跳转&#xff…

Jenkins实现基础CI操作配合python

条件&#xff1a; gitlab准备好 jenkins准备好 (不会java项目, 故跳过Maven打jar包) jenkins配置 在配置里通过插件Git Parameter配置Git&#xff0c;以便于从gitlab 拉去代码到Jenkins r容器内 /var/jenkins_home/ 刚接触python 项目好像不需要构建&#xff0c;直接推送到远…