权限即不同用户可以使用不同功能

实现前置:

在上一次登录与校验中,我们将authentication存入到SecurityContextHolder中,后续我们需要从FilterSecurityInterceptor取出并进行验证

基于注解实现

开启相关配置(放在config里)

@EnableGlobalMethodSecurity(prePostEnabled = true) //适用于springboot2
@EnableMethodSecurity(prePostEnabled = true) //适用于springboot3

对应主要注解

@PreAuthorize("hasAuthority('ROLE_USER')")

需要修改的有两部分:

1.在我们自定义的UserDetailService中我们重写了loadUserByUsername:返回的LoginUser还包括了权限。在上一次,我们仅仅向里封装了一个User信息。除此以外,我们还需要一个权限信息,因此基于上次的User信息,我们对LoginUser增加了成员变量

@Data
@NoArgsConstructor
public class LoginUser implements UserDetails {
private User user;
private List<String> permissions;
// 这里不进行序列化/反序列化的原因是SimpleGrantedAuthority没实现序列化,而且我们已经有permissions,可直接通过get方法获取authorities
// 其实他可以不做成员变量,但是这样可以节省系统开销:不必多次创建authorities
@JSONField(serialize = false)
private List<SimpleGrantedAuthority> authorities;

public LoginUser(User user, List<String> permissions) {
this.user = user;
this.permissions = permissions;
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
if(this.authorities!=null){
return this.authorities;
}
//如何选定的simplegrantedauthority:
// 通过查看grantedAuhority源码,通过ctrl+alt点击这个接口,我们发现他有三个实现类,我们从中选择其一
// 本方法即把string转换为相关的权限类型以便于preAuthorize(hasAuthority(''))使用
this.authorities=this.permissions.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());
return this.authorities;
}

@Override
public String getPassword() {
return user.getPassword();
}

@Override
public String getUsername() {
return user.getUserName();
}

@Override
public boolean isAccountNonExpired() {
return true;
}

@Override
public boolean isAccountNonLocked() {
return true;
}

@Override
public boolean isCredentialsNonExpired() {
return true;
}

@Override
public boolean isEnabled() {
return true;
}
}

2.在拦截器中写入对应的权限信息

 SecurityContextHolder.getContext().
setAuthentication(new UsernamePasswordAuthenticationToken(loginUser,null,loginUser.getAuthorities()));

异常:异常一般有两种:登录不上去,权限不够

1.登录失败(身份入口)新增异常处理

@Component
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
ResponseResult result = new ResponseResult(HttpStatus.UNAUTHORIZED.value(),"用户认证失败!请重新登录");
String json= JSON.toJSONString(result);
WebUtil.renderString(response, json);
}
}

2.权限不足新增异常处理

@Component
public class AccessDeniedHandlerImpl implements AccessDeniedHandler {

@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
ResponseResult result = new ResponseResult(HttpStatus.FORBIDDEN.value(),"用户权限不足!");
String json= JSON.toJSONString(result);
WebUtil.renderString(response, json);
}
}

WebUtil

public class WebUtil {
/**
* 将字符串渲染到客户端
*
* @param response 渲染对象
* @param string 待渲染的字符串
* @return null
*/
public static String renderString(HttpServletResponse response, String string) {
try {
response.setStatus(200);
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().print(string);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

修改securityConfig

// 添加异常处理器
http
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedHandler(accessDeniedHandler);
 

springsecurity:权限与异常处理的更多相关文章

  1. SpringSecurity权限管理系统实战—二、日志、接口文档等实现

    系列目录 SpringSecurity权限管理系统实战-一.项目简介和开发环境准备 SpringSecurity权限管理系统实战-二.日志.接口文档等实现 SpringSecurity权限管理系统实战 ...

  2. SpringSecurity权限管理系统实战—七、处理一些问题

    目录 SpringSecurity权限管理系统实战-一.项目简介和开发环境准备 SpringSecurity权限管理系统实战-二.日志.接口文档等实现 SpringSecurity权限管理系统实战-三 ...

  3. SpringSecurity权限管理系统实战—一、项目简介和开发环境准备

    目录 SpringSecurity权限管理系统实战-一.项目简介和开发环境准备 SpringSecurity权限管理系统实战-二.日志.接口文档等实现 SpringSecurity权限管理系统实战-三 ...

  4. SpringSecurity权限管理系统实战—四、整合SpringSecurity(上)

    目录 SpringSecurity权限管理系统实战-一.项目简介和开发环境准备 SpringSecurity权限管理系统实战-二.日志.接口文档等实现 SpringSecurity权限管理系统实战-三 ...

  5. SpringSecurity权限管理系统实战—六、SpringSecurity整合jwt

    目录 SpringSecurity权限管理系统实战-一.项目简介和开发环境准备 SpringSecurity权限管理系统实战-二.日志.接口文档等实现 SpringSecurity权限管理系统实战-三 ...

  6. SpringSecurity权限管理系统实战—八、AOP 记录用户、异常日志

    目录 SpringSecurity权限管理系统实战-一.项目简介和开发环境准备 SpringSecurity权限管理系统实战-二.日志.接口文档等实现 SpringSecurity权限管理系统实战-三 ...

  7. SpringSecurity权限管理系统实战—九、数据权限的配置

    目录 SpringSecurity权限管理系统实战-一.项目简介和开发环境准备 SpringSecurity权限管理系统实战-二.日志.接口文档等实现 SpringSecurity权限管理系统实战-三 ...

  8. spring-security权限控制详解

    在本例中,主要讲解spring-boot与spring-security的集成,实现方式为: 将用户.权限.资源(url)采用数据库存储 自定义过滤器,代替原有的 FilterSecurityInte ...

  9. SpringSecurity权限管理系统实战—五、整合SpringSecurity(下)

    系列目录 前言 上篇文章SpringSecurity整合了一半,这次把另一半整完,所以本篇的序号接着上一篇. 七.自定义用户信息 前面我们登录都是用的指定的用户名和密码或者是springsecurit ...

  10. sonar + jacoco + mockMvc 模拟session 用户登录 配合SpringSecurity 权限 快速测试代码覆盖率.

    遇到mock 测试简直就是神器,特别是要做代码覆盖率,直接测试controller就好了,缺点,虽然可以回滚事务,但是依赖数据库数据,解决,根据SpringBoot ,再建立一个专门跑单元测试的数据库 ...

随机推荐

  1. NumPy 二项分布生成与 Seaborn 可视化技巧

    二项分布 简介 二项分布是一种离散概率分布,用于描述在固定次数的独立试验中,事件"成功"的次数的概率分布.它通常用于分析诸如抛硬币.做选择题等具有两个结果(成功或失败)的事件. 参 ...

  2. 《iOS面试之道》-“串行队列的代码实战” 勘误

    一.原书第一版154页开始讲解串行队列.并发队列.以及在Dispatch_Async.Dispatch_Sync下面的作用 最后一段代码: if(_q == NULL) { _q = dispatch ...

  3. C语言打印数字前补0

    1.要求说明 例如有个数据为a = 0x10,要求打印输出为0x000010. 2.实现 1 #include <stdio.h> 2 3 4 int main() 5 { 6 int a ...

  4. npm包管理器 切换npm源 使用nrm来管理npm镜像源

    npm是NodeJs项目模块管理工具,它已经集成了nodejs安装包中,在npm从从5.2版开始,增加了 npx 命令(解决的主要问题,就是调用项目内部安装的模块,很多工具不再需要npm -g 全局来 ...

  5. 【简写Mybatis-02】注册机的实现以及SqlSession处理

    前言 注意: 学习源码一定一定不要太关注代码的编写,而是注意代码实现思想: 通过设问方式来体现代码中的思想:方法:5W+1H 源代码: https://gitee.com/xbhog/mybatis- ...

  6. 搜狗五笔 date 自定义时间格式

    搜狗五笔 date 自定义时间格式 搜狗五笔 date 默认打出的是"2023-6-15",如果需要"2023-06-15",则需要在自定义短语中设置 属性设置 ...

  7. Steam Epic 启动程序默认地址

    Steam Epic 启动程(启动器)序默认地址 "D:\Games\EpicAPP\Epic Games\Launcher\Portal\Binaries\Win32\EpicGamesL ...

  8. C#.NET Rsa私钥加密公钥解密

    在C#中,RSA私钥只能签名,不能加密,如果要加密,要借助BouncyCastle库. nuget 中引用 Portable.BouncyCastle. 工具类: RsaEncryptUtil usi ...

  9. javascript 类class设置访问器setter时出现Maximum call stack size exceeded错误

    Maximum call stack size exceeded这个错误的意思是调用栈溢出,但是自己写的代码基本不可能出现.所以可能的原因是A调用了B,然后B再调用A,形成了循环调用.或者说是A自己调 ...

  10. Vue微前端架构与Qiankun实践理论指南

    title: Vue微前端架构与Qiankun实践理论指南 date: 2024/6/15 updated: 2024/6/15 author: cmdragon excerpt: 这篇文章介绍了微前 ...