SpringSecurity学习笔记(十二)异常以及权限管理使用

2023-10-27

参考视频

异常

SS中的异常主要分为两种

AuthenticationException authenticationException;//认证异常
AccessDeniedException accessDeniedException;//授权异常

在这里插入图片描述
在这里插入图片描述
我们在数据库中插入数据
在这里插入图片描述
在这里插入图片描述
此时我们登录id为1的用户,
在这里插入图片描述
在这里插入图片描述
自定义异常处理

.and()
                .exceptionHandling()
                .accessDeniedHandler(new AccessDeniedHandler() {
                    @Override
                    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
                        response.setStatus(HttpStatus.FORBIDDEN.value());
                        response.setContentType("application/json;charset=utf-8");
                        response.getWriter().write("无权限访问。");
                        response.flushBuffer();
                    }
                })
                .authenticationEntryPoint(new AuthenticationEntryPoint() {
                    @Override
                    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
                        response.setStatus(HttpStatus.UNAUTHORIZED.value());
                        response.setContentType("application/json;charset=utf-8");
                        response.getWriter().write("尚未认证,请进行认证操作!");
                        response.flushBuffer();
                    }
                })

如果我们登录了其他的无权限的用户进行访问则出现。
在这里插入图片描述

源码分析:这里面涉及到一个类FilterSecurityInterceptor里面的方法

public void invoke(FilterInvocation fi) throws IOException, ServletException {
		if ((fi.getRequest() != null)
				&& (fi.getRequest().getAttribute(FILTER_APPLIED) != null)
				&& observeOncePerRequest) {
			// filter already applied to this request and user wants us to observe
			// once-per-request handling, so don't re-do security checking
			fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
		}
		else {
			// first time this request being called, so perform security checking
			if (fi.getRequest() != null && observeOncePerRequest) {
				fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);
			}
//这里面会进行判断当前这个请求需要什么权限,用户有没有权限
			InterceptorStatusToken token = super.beforeInvocation(fi);

			try {
				fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
			}
			finally {
				super.finallyInvocation(token);
			}

			super.afterInvocation(token, null);
		}
	}
protected InterceptorStatusToken beforeInvocation(Object object) {
		Assert.notNull(object, "Object was null");
		final boolean debug = logger.isDebugEnabled();

		if (!getSecureObjectClass().isAssignableFrom(object.getClass())) {
			throw new IllegalArgumentException(
					"Security invocation attempted for object "
							+ object.getClass().getName()
							+ " but AbstractSecurityInterceptor only configured to support secure objects of type: "
							+ getSecureObjectClass());
		}
		//下面这个方法判断当前这个请求路径是否需要什么权限
		Collection<ConfigAttribute> attributes = this.obtainSecurityMetadataSource()
				.getAttributes(object);

		if (attributes == null || attributes.isEmpty()) {
			if (rejectPublicInvocations) {
				throw new IllegalArgumentException(
						"Secure object invocation "
								+ object
								+ " was denied as public invocations are not allowed via this interceptor. "
								+ "This indicates a configuration error because the "
								+ "rejectPublicInvocations property is set to 'true'");
			}

			if (debug) {
				logger.debug("Public object - authentication not attempted");
			}

			publishEvent(new PublicInvocationEvent(object));

			return null; // no further work post-invocation
		}

		if (debug) {
			logger.debug("Secure object: " + object + "; Attributes: " + attributes);
		}

		if (SecurityContextHolder.getContext().getAuthentication() == null) {
			credentialsNotFound(messages.getMessage(
					"AbstractSecurityInterceptor.authenticationNotFound",
					"An Authentication object was not found in the SecurityContext"),
					object, attributes);
		}

		Authentication authenticated = authenticateIfRequired();

		// Attempt authorization
		try {
			//这里对当前的用户进行权限的判断
			this.accessDecisionManager.decide(authenticated, object, attributes);
		}
		catch (AccessDeniedException accessDeniedException) {
			publishEvent(new AuthorizationFailureEvent(object, attributes, authenticated,
					accessDeniedException));

			throw accessDeniedException;
		}

		if (debug) {
			logger.debug("Authorization successful");
		}

		if (publishAuthorizationSuccess) {
			publishEvent(new AuthorizedEvent(object, attributes, authenticated));
		}

		// Attempt to run as a different user
		Authentication runAs = this.runAsManager.buildRunAs(authenticated, object,
				attributes);

		if (runAs == null) {
			if (debug) {
				logger.debug("RunAsManager did not change Authentication object");
			}

			// no further work post-invocation
			return new InterceptorStatusToken(SecurityContextHolder.getContext(), false,
					attributes, object);
		}
		else {
			if (debug) {
				logger.debug("Switching to RunAs Authentication: " + runAs);
			}

			SecurityContext origCtx = SecurityContextHolder.getContext();
			SecurityContextHolder.setContext(SecurityContextHolder.createEmptyContext());
			SecurityContextHolder.getContext().setAuthentication(runAs);

			// need to revert to token.Authenticated post-invocation
			return new InterceptorStatusToken(origCtx, true, attributes, object);
		}
	}
public void decide(Authentication authentication, Object object,
			Collection<ConfigAttribute> configAttributes) throws AccessDeniedException {
		int deny = 0;

		for (AccessDecisionVoter voter : getDecisionVoters()) {
			int result = voter.vote(authentication, object, configAttributes);

			if (logger.isDebugEnabled()) {
				logger.debug("Voter: " + voter + ", returned: " + result);
			}

			switch (result) {
			case AccessDecisionVoter.ACCESS_GRANTED:
				return;

			case AccessDecisionVoter.ACCESS_DENIED:
				deny++;

				break;

			default:
				break;
			}
		}

		if (deny > 0) {
			throw new AccessDeniedException(messages.getMessage(
					"AbstractAccessDecisionManager.accessDenied", "Access is denied"));
		}

		// To get this far, every AccessDecisionVoter abstained
		checkAllowIfAllAbstainDecisions();
	}

在这里插入图片描述
在这里插入图片描述
参考文章

权限管理

SpringSecurity提供了两种权限管理的策略。

FilterSecurityInterceptor:基于过滤器的权限管理,将请求拦截下来根据http请求的地址进行权限的校验你。这种方式是请求到达方法之前进行处理的。
MethodSecurityInterceptor:基于方法级别的拦截处理,利用的是aop的思想,这种是请求到达方法在方法调用前执行。

基于方法的权限管理

下面这几个注解想要生效,必须在配置类上面加上@EnableGlobalMethodSecurity(jsr250Enabled = true,prePostEnabled = true,proxyTargetClass = true,securedEnabled = true)表示启用这些注解。

@PreAuthorize("hasRole('admin')")
@PostAuthorize("")
@PreFilter("")

在这里插入图片描述

在这里插入图片描述

@GetMapping("/admin/test")
    @PreAuthorize("hasRole('admin') and authentication.name=='dongmu'")
    //#name取得是接口上面的参数
    @PostAuthorize("authentication.name == #name")
    @PreFilter("hasAuthority('admin')")
    @ResponseBody
    public String admin(String name){
        return "这是一个admin用户才能访问的界面。";
    }
    @GetMapping("/public/filter")
    //下面这个表达式表示只是保留值是奇数的结果
    @PreFilter(value = "filterObject%2!=0",filterTarget = "list")
    public void filter(@RequestParam("ids") List<Integer> list){
        for (Integer integer : list) {
            System.out.println(integer);
        }
    }

    //下面这个是或的关系,只要拥有一个权限就可以访问这个接口
    @Secured({"ROLE_admin","ROLE_user"})
    @GetMapping("/public/secure")
    public void secure(){
        System.out.println("secure测试");
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringSecurity学习笔记(十二)异常以及权限管理使用 的相关文章

  • 如何查看Pocketsphinx词典中是否存在该单词?

    我只是想看看字典文件中是否存在字符串 字典文件位于问题底部 我想检查语音识别器是否可以识别单词 例如 识别器将无法识别字符串ahdfojakdlfafiop 因为字典中没有定义 所以 我可以检查某个单词是否在 pocktsphinx 词典中
  • Spring控制器是线程安全的吗

    我遇到了这个控制器示例 想知道它是否是线程安全的 我特别想知道 gson 实例变量 import org springframework stereotype Controller import org springframework we
  • 任务“:app:dexDebug”执行失败

    我目前正在处理我的项目 我决定将我的 Android Studio 更新到新版本 但在我导入项目后 它显示如下错误 Information Gradle tasks app assembleDebug app preBuild UP TO
  • java中的csv到pdf文件

    我正在尝试获得一个csv文件解析为pdf 到目前为止我所拥有的内容附在下面 我的问题是这段代码最终出现在 pdf 中的文件在 csv 文件的第一行被截断 我不明白为什么 附示例 本质上我想要一个没有任何操作的 csv 文件的 pdf 版本
  • 如何在 Eclipse 中用阿拉伯语读写

    我在 eclipse 中编写了这段代码来获取一些阿拉伯语单词 然后打印它们 public class getString public static void main String args throws Exception PrintS
  • 将链接对象转换为流或集合

    我想迭代堆栈跟踪 堆栈跟踪由可抛出对象组成 其 getCause 返回下一个可抛出对象 最后一次调用 getCause 返回 null 示例 a gt b gt null 我尝试使用 Stream iterable 这会导致 NullPoi
  • 如何从另一个xml文件动态更新xml文件?

    我想从另一个 xml 文件更新 xml 文件 我使用了一个 xml 文件 如下所示 one xml
  • JTree 节点不会被直观地选择

    不知何故 我无法为我的 JTree 节点启用 选择突出显示 我正在我的项目中使用自定义单元格渲染器 这很可能导致此问题 这是完整的渲染器类代码 protected class ProfessionTreeCellRenderer exten
  • 无法加载 jar 文件的主类

    我使用 Eclipse IDE 开发了一个应用程序 创建应用程序后 我以 jar 格式导出项目 当我尝试运行此 jar 文件时 出现错误 无法加载主类 请帮忙 当您将项目导出为 jar 时 请参阅此所以问题 https stackoverf
  • 通过 InjectMocks Spy 注入对象

    我需要对一个类运行一系列单元测试 该类具有 Autowired Logger 实现 实现的基本思想是 Mock Logger logger InjectMocks TestedClass tested 但我想保存日志输出功能 Mockito
  • 如何解决 onEditCommit 事件上的类型不匹配错误?

    我在 Fxml 中使用 onEditCommit 事件在用户编辑数据后检索数据 FXML 代码
  • Google Inbox 类似 RecyclerView 项目打开动画

    目前 我正在尝试实现 Google Inbox 例如RecyclerView行为 我对电子邮件打开动画很好奇 我的问题是 该怎么做 我的意思是 他们使用了哪种方法 他们用过吗ItemAnimator dispatchChangeStarti
  • Java 重写 hashCode() 得到 StackOverflowError

    所以我不太熟悉重写 hashCode 并且我似乎在 hashCode 方法中以某种方式进行了一些无限递归 这是我的场景 我有一个 DuplicateCache 类 它是一个缓存对象 用于检查系统中的重复对象 我有一个静态内部类 Duplic
  • 服务器到 Firebase HTTP POST 结果为响应消息 200

    使用 Java 代码 向下滚动查看 我使用 FCM 向我的 Android 发送通知消息 当提供正确的服务器密钥令牌时 我收到如下所示的响应消息 之后从 FCM 收到以下响应消息 Response 200 Success Message m
  • cucumber-junit-platform-engine 中的功能文件发现

    In cucumber junit我使用的库 CucumberOptions定义功能文件位置 package com mycompany cucumber import cucumber api CucumberOptions import
  • 打印包含 JBIG2 图像的 PDF

    请推荐一些库 帮助我打印包含 JBIG2 编码图像的 PDF 文件 PDFRenderer PDFBox别帮我 这些库可以打印简单的 PDF 但不能打印包含 JBIG2 图像的 PDF PDFRenderer尝试修复它 根据 PDFRedn
  • 为什么 ConcurrentHashMap::putIfAbsent 比 ConcurrentHashMap::computeIfAbsent 更快?

    使用 ConcurrentHashMap 我发现computeIfAbsent 比putIfAbsent 慢两倍 这是简单的测试 import java util ArrayList import java util List import
  • OpenJDK 版本控制

    上下文 我想确保我们系统上安装的 Java 不受 CVE 2022 21449 的影响 java version 给出 openjdk version 11 0 7 2020 04 14 LTS OpenJDK Runtime Enviro
  • 阻止 OSX 变音符号为所有用户禁用 Java 中的 KeyBindings?

    注 我知道这个问题 https stackoverflow com questions 40335285 java keybinds stop working after holding down a key用户必须输入终端命令才能解决此问
  • struts 教程或示例

    我正在尝试在 Struts 中制作一个登录页面 这个想法是验证用户是否存在等 然后如果有错误 则返回到登录页面 错误显示为红色 典型的登录或任何表单页面验证 我想知道是否有人知道 Struts 中的错误管理教程 我正在专门寻找有关的教程 或

随机推荐

  • csdn博客推荐系统实战-5文本聚类-话题模型LDA

    话题模型topic model是自然语言处理领域里面热门的一个技术 可以用来做很多的事情 例如相似度比较 关键词提取 分类 还有就是具体产品业务上的事了 总之可以干很多的事情 今天不会讲LDA模型的很多细节和原理 没有满屏的数学公式 只讲一
  • OpenGL光源位置

    一 OpenGL光源简介 OpenGL提供了多种形式的光源 如点光源 平行光源和聚光灯光源等 所有光源都使用 glLight 接口来设置光源属性 其中包括 glLight if 和 glLight if v 两类 1 示例光源 GLfloa
  • 下载好unity后打开出现这个弹窗怎么解决

    unity我重新下了两遍 始终出现这个弹窗 无法打开unity 始终找不到许可 急求 谢谢
  • Matlab 中三角函数

    Matlab 中三角函数 atan2 基本数学函数 abs 绝对值 acos 反余弦 acosh 反双曲余弦函数 acot 反余切 acoth 反双曲线余切 acsc 反余割 acsch 反双曲线余割 angle 相位角 asec 反正割
  • Materials Studio工具模块介绍

    相关教程和破解版软件包下载链接为 https blog csdn net qwxwaty article details 80402505 各模块细节介绍 Materials Visualizer Materials visualizer
  • 总结ctf中 MD5 绕过的一些思路

    总结ctf中 MD5 绕过的一些思路 1 常规的0e绕过 2 数组绕过 3 强类型绕过 4 a md5 a 5 md5 与SQL注入 a b md5 a md5 b sha1 a sha1 b 1 常规的0e绕过 QNKCDZO 24061
  • mapbox 在 vue2 中的使用

    一 Mapbox 在 vue 中的使用 安装 mapbox mapbox gl geocoder npm install save mapbox mapbox gl geocoder 安装 mapbox mapbox gl language
  • (三)原生JavaScript----Ajax的Get请求和Post请求

    三 原生JavaScript使用Ajax的步骤 Router js中有get post接口 一 定义一个ajax函数 const ajax function 二 获取节点值 Ajax函数中 let username document get
  • golang时间-时间戳的获取-转换-计算

    一 获取时间 1 1 获取当前时间 代码实现 package main import fmt time func main currentTime time Now 当前时间 currentYear time Now Year 当前年 cu
  • 浅谈Spring

    Spring是一个轻量级的控制反转 IoC 和面向切面 AOP 的容器 框架 一 什么是IOC IoC Inversion of Control 翻译成中 是 控制反转 的意思 也就是说 Spring 是 个 控制反转 的容器 1 1控制反
  • python可视化学习七(边缘箱型图)

    边缘箱线图 箱图是用来显示变量分布的统计图 直方图更看重与在取值范围内的分布 而箱线图更看重于观察变量间的重要分割点 箱线图能够显示数据分布的关键数据的节点 常用来作为查找异常值的方式 1当直方图的分布越接近正态分布 箱线图就会越对称 2直
  • 栈区,堆区,全局区,文字常量区,程序代码区 详解

    原博地址 http blog csdn net yitian20000 article details 6358837 感觉这篇文章讲的很清晰 很详细 一 预备知识 程序的内存分配 一个由C C 编译的程序占用的内存分为以下几个部分 1 栈
  • typora用户指南

    Typora 一直是我认为桌面端笔记应用应有的终极形态 用我之前 一篇文章 中的话来说就是 它的功能之强大 设计之冷静 体验之美妙 理念之先进 我认为值得所有笔记应用厂商学习 但一件很尴尬的事情是 由于它极简的设计理念 有许多使用者并没能完
  • liunx ftp 421 passive mode refused([linux]配置 vsftp 启用被动模式(passive mode)解决客户端“no route to host“错误)

    系统 CentOS 修改 vsftpd conf 启用被动模式 指定端口 pasv min port 12000 pasv max port 12199 pasv enable YES 配置防火墙 iptables 允许端口访问 iptab
  • vue2项目(二)---Header、Footer

    非路由组件 Header Footer 首页 搜索页 路由组件 Home首页 Search搜索 login登录 无Footer register注册 无Footer 开发项目的步骤 1 书写静态页面 HTML CSS 2 拆分组件 路由 非
  • 华为机试:敏感字段加密

    题目来源 华为机试 敏感字段加密 题目描述 题目解析 要求 删除命令字前后多余的下换线 对指定索引的敏感字段进行加密 替换为 无法找到指定索引的命令字 输出字符串ERROR 分析 如果遇到大小写字母 数字 这一定是密码 可能需要替换成6个
  • Qt 使用共享库

    创建动态库工程 选择模块需要注意的是如果想要将GUI封装成一个动态库 那么必须要要将QtWidgets选中 不然是不能生成ui xxx h头文件的 接下来直接都下一步直到创建好就好 创建好之后会有两个头文件 一个 cpp文件 Global
  • 数据清洗遇到的问题思考

    因为本次任务是基础的数据预处理和数据集划分 所以本次讨论不涉及特征工程和模型相关的 问题一 缺失数据 有很多人问到了缺失值处理的问题 统一汇总提问 为什么需要处理缺失值 确实值会影响模型训练 某些特征值确实 有可能使得该条样本完全是负样本
  • VM6289:1 http://xxx.cn 不在以下 request 合法域名列表中,请参考文档:https://developers.weixin.qq.com/miniprogra

    本地测试时 点击微信开发工具右上角详情 然后勾选上 不校验合法域名
  • SpringSecurity学习笔记(十二)异常以及权限管理使用

    参考视频 异常 SS中的异常主要分为两种 AuthenticationException authenticationException 认证异常 AccessDeniedException accessDeniedException 授权