SpringSecurity【3】之授权

继续昨天的认证,今天来分析

在Spring Security中,授权是指对用户访问系统资源的限制。Spring Security提供了多种授权方式,包括基于角色的授权、基于表达式的授权、注解授权等。

基于角色的授权是指通过为用户分配不同的角色来限制其访问系统资源。Spring Security提供了一些默认的角色,如ROLE_USER和ROLE_ADMIN等,也支持开发者自定义角色。在Spring Security中,我们可以使用标签<intercept-url>和<http>来配置基于角色的授权。下面是一个例子:

<http> <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" /> </http>

上述配置表示只有拥有ROLE_ADMIN角色的用户才能访问/admin/**下的资源。

Spring Security还提供了注解授权、方法级授权等多种授权方式,可以根据具体需求进行选择和配置。

分析前端传来的值:

访问:得到了json的对象

(关于权限:就是往数据库中放字段,设置了就有)

通过流的视图方式查看:

代码:

MyUserDtealsService
package com.lya.securty.config;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lya.securty.pojo.*;
import com.lya.securty.service.IModuleService;
import com.lya.securty.service.IRoleModuleService;
import com.lya.securty.service.IUserRoleService;
import com.lya.securty.service.IUserService;
import com.lya.securty.service.impl.ModuleServiceImpl;
import com.lya.securty.service.impl.RoleModuleServiceImpl;
import com.lya.securty.service.impl.RoleServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
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.Component;import java.util.List;
import java.util.stream.Collectors;@Component
//把他编程一个组件
public class MyUserDtealsService implements UserDetailsService {@Autowiredprivate IUserService userService;@Autowiredprivate IUserRoleService iUserRoleService;@Autowiredprivate ModuleServiceImpl moduleService;@Autowiredprivate RoleServiceImpl roleService;@Autowiredprivate RoleModuleServiceImpl roleModuleService;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User user = userService.getOne(new QueryWrapper<User>().eq("username", username));if (user == null) {throw new UsernameNotFoundException("用户无效");}
//        1.查出所有的身份, map遍历,返回新数据-->流,将流编程list
//        2.多个id对应的权限,连接权限表List<Integer> role_ids = iUserRoleService
//        查出所有的身份.list(new QueryWrapper<UserRole>().eq("user_id", user.getId()))
//                .stream().map(r->r.getUserId());
//        返回新数据-->流.stream().map(UserRole::getUserId)
//                将流编程list.collect(Collectors.toList());
//         用id查询身份对一的名字---比如1,2普通用户超级管理。List<String> roles = roleService.list(new QueryWrapper<Role>().in("role_id", role_ids))//        返回新数据-->流.stream().map(Role::getRoleName)
//                将流编程list.collect(Collectors.toList());//        根据身份id查询权限List<Integer> module_ids = roleModuleService.list(new QueryWrapper<RoleModule>().in("role_id", role_ids))
//        返回新数据-->流.stream().map(RoleModule::getModuleId)
//                将流编程list.collect(Collectors.toList());
//      根据权限id查询权限List<String> moudelse = moduleService.list(new QueryWrapper<Module>().in("id", module_ids))//        返回新数据-->流.stream().map(Module::getUrl)
//                .filter(Object::nonNull)
//                将流编程list.collect(Collectors.toList());//        roles[权限]
//        modules 访问urlroles.addAll(moudelse);List<SimpleGrantedAuthority> authorities = roles.stream().map(e -> {return new SimpleGrantedAuthority(e);}).collect(Collectors.toList());user.setAuthorities(authorities);return user;}}

WebSecurityConfig
package com.lya.securty.config;import com.fasterxml.jackson.databind.ObjectMapper;
import com.lya.securty.resp.JsonResponseBody;
import com.lya.securty.resp.JsonResponseStatus;
import com.lya.securty.service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.web.bind.annotation.ResponseBody;import javax.sql.DataSource;/*** @author all*/
@Configuration//启动配置类 spring进行管理不然加载不了这个类
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
//开启这个类
public class WebSecurityConfig {@Autowired
private DataSource dataSource;//SpringBoot自己帶的一個序列化的类@Autowiredprivate ObjectMapper objectMapper;/*** 配置持久化Token方式,注意tokenRepository.setCreateTableOnStartup()配置*/@Beanpublic PersistentTokenRepository persistentTokenRepository(){JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();tokenRepository.setDataSource(dataSource);// 设置为true要保障数据库该表不存在,不然会报异常哦// 所以第二次打开服务器应用程序的时候得把它设为falsetokenRepository.setCreateTableOnStartup(false);return tokenRepository;}
//    加密类@Bean
//    @Primarypublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}/*** 配置密码编码器,首次采用明文密码方式进行比对校验*/
//    @Bean
//    public PasswordEncoder passwordEncoder(){
//        return NoOpPasswordEncoder.getInstance();
//    }@Autowiredprivate UserServiceImpl userService;@Autowiredprivate MyUserDtealsService myUserDtealsService;
//    @Bean
//    public UserDetailsService userDetailsService() {
//        UserDetails admin = User.withUsername("admin")
//                .password(bcryptPasswordEncoder().encode("123456"))
//                .roles("ADMIN", "USER").build();//权限
//        UserDetails user = User.withUsername("user")
//                .password(bcryptPasswordEncoder().encode("123456"))
//                .roles("USER").build();
//        return new InMemoryUserDetailsManager(admin, user);
//    }/*** 获取AuthenticationManager(认证管理器),登录时认证使用(基于数据库方式)* @return provider* @throws Exception 异常*/@Beanpublic AuthenticationManager authenticationManager() throws Exception {//创建DaoAuthenticationProviderDaoAuthenticationProvider provider=new DaoAuthenticationProvider();//设置userDetailsService,基于数据库方式进行身份认证provider.setUserDetailsService(myUserDtealsService);//配置密码编码器provider.setPasswordEncoder(passwordEncoder());return new ProviderManager(provider);}@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {//认证请求http.authorizeRequests()//antMatchers匹配对应的路径//permitAll允许访问.antMatchers("/toLogin").permitAll()//hasRole具备身份//hasAnyRole具备多个身份.antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasAnyRole("ADMIN", "USER")//anyRequest其余所有请求.anyRequest()//authenticated认证.authenticated().and().formLogin()//当前登录页面.loginPage("/toLogin")//设置处理登录请求的接口.loginProcessingUrl("/userLogin")//用户的数据参数.usernameParameter("username").passwordParameter("password")//转发  进入首页  地址栏不改变//.successForwardUrl("/index")//成功处理器.successHandler((req,resp,auth)->{Object user = auth.getPrincipal();JsonResponseBody.success(user);//重定向  跳转首页
//                    resp.sendRedirect("/index");
//                    这里不要直接跳,应为适应前后端分离
//                    (通过流的方式,响应数据到前端)objectMapper.writeValue(resp.getOutputStream(),JsonResponseBody.success(user));})//失败处理器.failureHandler((req,resp,ex)->{//错误信息提示req.setAttribute("msg",ex.getMessage());//重定向  跳转登录req.getRequestDispatcher("/toLogin").forward(req,resp);}).and().exceptionHandling()
//                .accessDeniedPage((req,resp,ex)->{
//                    //错误信息提示无权限
//                    objectMapper
//                            .writeValue(resp.getOutputStream(),JsonResponseBody.other(JsonResponseStatus.NO_LOGIN));
//                })//              五登录.authenticationEntryPoint((req,resp,ex)->{objectMapper.writeValue(resp.getOutputStream(),JsonResponseBody.other(JsonResponseStatus.NO_LOGIN));}).and().logout().logoutUrl("/logout").logoutSuccessUrl("/").and().rememberMe()// 指定 rememberMe 的参数名,用于在表单中携带 rememberMe 的值。.rememberMeParameter("remember-me")// 指定 rememberMe 的有效期,单位为秒,默认2周。.tokenValiditySeconds(300)// 指定 rememberMe 的 cookie 名称。.rememberMeCookieName("remember-me-cookie")// 指定 rememberMe 的 token 存储方式,可以使用默认的 PersistentTokenRepository 或自定义的实现。.tokenRepository(persistentTokenRepository())// 指定 rememberMe 的认证方式,需要实现 UserDetailsService 接口,并在其中查询用户信息。.userDetailsService(userService);
//        防禦http.csrf().disable();http.exceptionHandling().accessDeniedPage("/noAccess");return http.build();}}

UserController(添加两个具有访问权限的)
package com.lya.securty.controller;import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;/*** @author all*/
@Controller
public class UserController {@RequestMapping("/toLogin")public String toLogin() {return "login";}@RequestMapping("/userLogin")public String userLogin(String username, String password) {System.out.println("username=" + username + ",password=" + password);return "index";}@RequestMapping("/admin/toAddUser")public String toAddUser() {return "admin/addUser";}@RequestMapping("/admin/toListUser")public String toListUser() {return "admin/listUser";}@RequestMapping("/admin/toResetPwd")public String toResetPwd() {return "admin/resetPwd";}@RequestMapping("/admin/toUpdateUser")public String toUpdateUser() {return "admin/updateUser";}@RequestMapping("/user/toUpdatePwd")public String toUpdatePwd() {return "user/updatePwd";}@RequestMapping("/index")public String index(){return "index";}@ResponseBody@RequestMapping("/add")@PreAuthorize("hasAuthority('book:manager:add')")public String add() {return "订单新增";}@ResponseBody@RequestMapping("/oradd")@PreAuthorize("hasAuthority('order:manager:add')")public String oradd() {return "订单新增";}@RequestMapping("/noAccess")public String noAccess() {return "accessDenied";}}
JsonResponseBody(返回前端的Json格式数据)
package com.lya.securty.resp;import lombok.Data;@Data
public class JsonResponseBody<T> {private Integer code;private String msg;private T data;private Long total;private JsonResponseBody(JsonResponseStatus jsonResponseStatus, T data) {this.code = jsonResponseStatus.getCode();this.msg = jsonResponseStatus.getMsg();this.data = data;}private JsonResponseBody(JsonResponseStatus jsonResponseStatus, T data, Long total) {this.code = jsonResponseStatus.getCode();this.msg = jsonResponseStatus.getMsg();this.data = data;this.total = total;}public static <T> JsonResponseBody<T> success() {return new JsonResponseBody<T>(JsonResponseStatus.OK, null);}public static <T> JsonResponseBody<T> success(T data) {return new JsonResponseBody<T>(JsonResponseStatus.OK, data);}public static <T> JsonResponseBody<T> success(T data, Long total) {return new JsonResponseBody<T>(JsonResponseStatus.OK, data, total);}public static <T> JsonResponseBody<T> unknown() {return new JsonResponseBody<T>(JsonResponseStatus.UN_KNOWN, null);}public static <T> JsonResponseBody<T> other(JsonResponseStatus jsonResponseStatus) {return new JsonResponseBody<T>(jsonResponseStatus, null);}}

响应前端的msg

package com.lya.securty.resp;import lombok.Getter;@Getter
public enum JsonResponseStatus {OK(200, "OK"),UN_KNOWN(500, "未知错误"),RESULT_EMPTY(1000, "查询结果为空"),NO_ACCESS(3001, "没有权限"),NO_LOGIN(4001, "没有登录"),LOGIN_FAILURE(5001, "登录失败"),;private final Integer code;private final String msg;JsonResponseStatus(Integer code, String msg) {this.code = code;this.msg = msg;}}

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

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

相关文章

四、UART_阻塞发送中断接收

1、开发环境 (1)Keil MDK: V5.38.0.0 (2)MCU: mm320163D7P 2、实验目的&原理图 2.1、实验目的 (1)上位机串口助手给MCU发送信息&#xff0c;MCU串口通过通过串口助手接收后&#xff0c;将接收到的内容通过串口助手发送到上位机。 (2)串口在whil循环中每隔1秒发送一次…

蓝桥杯2020年5月青少组Python程序设计国赛真题

1、 上边是一个算法流程图,最后输出的b的值是() A.377 B.987 C.1597 D.2584 2、 3、如果整个整数X本身是完全平方数,同时它的每一位数字也都是完全平方数我们就称X 是完美平方数。前几个完美平方数是0、1、4、9、49、100、144......即第1个完美平方数是0,第2个是 1,第3个…

Hadoop入门学习笔记——一、VMware准备Linux虚拟机

视频课程地址&#xff1a;https://www.bilibili.com/video/BV1WY4y197g7 课程资料链接&#xff1a;https://pan.baidu.com/s/15KpnWeKpvExpKmOC8xjmtQ?pwd5ay8 Hadoop入门学习笔记&#xff08;汇总&#xff09; 目录 一、VMware准备Linux虚拟机1.1. VMware安装Linux虚拟机1.…

WEB 3D技术 three.js 通过lil-gui 控制x y z轴数值 操作分组 设置布尔值控制 颜色材质控制

上文 WEB 3D技术 three.js 通过lil-gui管理公共事件中 我们用 lil-gui 处理了一下基础事件和按钮的管理 那么 本文 我们来具体说说它能做的其他事 我们先将基础代码改成这样 import ./style.css import * as THREE from "three"; //引入lil-gui import { GUI } fro…

安装Kubernetes1.23、kubesphere3.4、若依项目自动打包部署到K8S记录

1.安装kubernetes1.23详细教程 kubernetes(k8s)集群超级详细超全安装部署手册 - 知乎 2.安装rancher动态存储 kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml3.安装kubesphere3.4 准备工作 您…

UE和Android互相调用

ue和android互调 这两种方式都是在UE打包的Android工程之上进行的。 一、首先是UE打包Android&#xff0c;勾选下面这项 如果有多个场景需要添加场景 工程文件在这个路径下 然后可以通过Android Studio打开&#xff0c;选择gradle打开 先运行一下&#xff0c;看看是否可以发布…

032 - STM32学习笔记 - TIM基本定时器(一) - 定时器基本知识

032 - STM32学习笔记 - TIM定时器&#xff08;一&#xff09; - 基本定时器知识 这节开始学习一下TIM定时器功能&#xff0c;从字面意思上理解&#xff0c;定时器的基本功能就是用来定时&#xff0c;与定时器相结合&#xff0c;可以实现一些周期性的数据发送、采集等功能&#…

DMR与DPMR以及DMR的分层

数字移动无线电 (DMR) 和数字专用移动无线电 (dPMR) 是数字对讲机中使用的流行通信技术。 与传统模拟无线电相比&#xff0c;这两种技术都提供了改进的音频质量、增强的安全功能和增加的网络容量。 但是&#xff0c;DMR 和 dPMR 无线电之间使用的技术存在重大差异&#xff…

2023年12月GESP Python五级编程题真题解析

【五级编程题1】 【试题名称】&#xff1a;小杨的幸运数 【问题描述】 小杨认为&#xff0c;所有大于等于a的完全平方数都是他的超级幸运数。 小杨还认为&#xff0c;所有超级幸运数的倍数都是他的幸运数。自然地&#xff0c;小杨的所有超级幸运数也都是幸运数。 对于一个…

MongoDB安装部署

二、安装部署 2.1 下载 下载地址&#xff1a;MongoDB Enterprise Server Download | MongoDB 当前最新版本6.0.9&#xff0c;5.0.9对Mac m1需要centos 8.2版本。选择docker安装。 2.2 docker-ce安装 # 安装docker # 默认repo源没有docker-ce安装包&#xff0c;需要新的rep…

Android 13 - Media框架(26)- OMXNodeInstance(三)

上一节我们了解了OMXNodeInstance中的端口定义&#xff0c;这一节我们一起来学习ACodec、OMXNode、OMX 组件使用的 buffer 到底是怎么分配出来的&#xff0c;以及如何关联起来的。&#xff08;我们只会去了解 graphic buffer的创建、input bytebuffer的创建、secure buffer的创…

免费更新UltraNews v2.8.0 已注册 – Laravel报纸,博客多语言系统,支持AI作家,内容生成器脚本

UltraNews v2.8.0 已注册 – Laravel报纸&#xff0c;博客多语言系统&#xff0c;支持AI作家&#xff0c;内容生成器脚本 一、概述 在网络内容创作与管理领域&#xff0c;UltraNews v2.8.0以其高度现代化和多功能性而独树一帜。这是一个基于Laravel框架构建的报纸、博客多语言…

实习课知识整理4:点击某个商品如何跳转到并展示出商品详情页

项目情景&#xff1a;当我们点击某个商品时&#xff0c;我们需要查看商品的具体的信息并进行购买的操作 简单理解以下就是&#xff0c;当我们点击一个url链接时&#xff0c;该链接需要携带一个参数到后端&#xff0c;一般设为商品的Id&#xff0c;然后后端通过Id从数据库中查找…

怎么卸载macOS上的爱思助手如何卸载macOS上的logitech g hub,如何卸载顽固macOS应用

1.在App Store里下载Cleaner One Pro &#xff08;注意&#xff0c;不需要订阅付费&#xff01;&#xff01;&#xff01;白嫖基础功能就完全够了&#xff01;&#xff01;&#xff01;&#xff09; 2.运行软件&#xff0c;在左侧目录中选择“应用程序管理”&#xff0c;然后点…

C++初阶——类和对象

呀哈喽&#xff0c;我是结衣 C入门之后&#xff0c;我们就进入了C的初阶的学习了&#xff0c;在了解类和对象之前&#xff0c;我们还是先了解&#xff0c;面向过程和面向对象的初步认识。 在本篇博客中&#xff0c;我们要讲的内容有 1.面向过程和面向对象初步认识 2.类的引入 3…

RasaGPT对话系统的工作原理

RasaGPT 结合了 Rasa 和 Langchain 这 2 个开源项目&#xff0c;当超出 Rasa 现有意图(out_of_scope)的时候&#xff0c;就会执行 ActionGPTFallback&#xff0c;本质上就是利用 Langchain 做了一个 RAG&#xff0c;调用 LLM API。RasaGPT 涉及的技术栈比较多而复杂&#xff0c…

面试官:看你简历了解过并发,我们简单聊一聊

前言&#xff1a; 今天和大家探讨最近的面试题&#xff0c;好久没有面试了&#xff0c;所以在此记录一下。本篇文章主要讲解CyclicBarrier和CountDownLatch的知识。该专栏比较适合刚入坑Java的小白以及准备秋招的大佬阅读。 如果文章有什么需要改进的地方欢迎大佬提出&#xf…

羊了个羊抓包速通,让第二关变成和第一关一样难度

目录 一.前言 二.前期准备 2.1抓包环境 2.2安装电脑版微信环境 2.3配置bp与浏览器VPN 2.4配置proxifier 三.开始抓包 3.1前期准备 3.2抓包ing 一.前言 羊了个羊是一款经典微信小程序游戏&#xff0c;号称“第一关谁都能过&#xff0c;第二关谁能过&#xff1f;“。那…

Python使用多线程解析超大日志文件

目录 一、引言 二、多线程基本概念 三、Python中的多线程实现 四、使用多线程解析超大日志文件 五、性能优化和注意事项 总结 一、引言 在处理大量数据时&#xff0c;单线程处理方式往往效率低下&#xff0c;而多线程技术可以有效地提高处理速度。Python提供了多种多线程…

详解Vue3中的内置组件(transition)

本文主要介绍Vue3中的内置组件&#xff08;transition&#xff09;的普通写法和setup写法。 目录 一、在普通写法中使用内置组件&#xff08;transition&#xff09;二、在setup写法中使用内置组件&#xff08;transition&#xff09;三、使用注意项 在Vue3中&#xff0c;内置了…