基于Spring Security Role过滤Jackson JSON输出内容
在本文中,我们将展示如何根据Spring Security中定义的用户角色过滤JSON序列化输出。
为什么我们需要过滤?
让我们考虑一个简单但常见的用例,我们有一个Web应用程序,为不同角色的用户提供服务。例如,这些角色为User和Admin。
首先,让我们定义一个要求,即Admin可以完全访问通过公共REST API公开的对象的内部状态。相反,User用户应该只看到一组预定义的对象属性。
我们将使用Spring Security框架来防止对Web应用程序资源的未授权访问。
让我们定义一个对象,我们将在API中作为REST响应返回数据:
class Item {private int id;private String name;private String ownerName;// getters
}
当然,我们可以为应用程序中的每个角色定义一个单独的数据传输对象类。但是,这种方法会为我们的代码库引入无用的重复或复杂的类层次结构。
另一方面,我们可以使用Jackson库的JSON View功能。正如我们将在下一节中看到的那样,它使得自定义JSON表示就像在字段上添加注释一样简单。
@JsonView注释
Jackson库支持通过使用@JsonView注解标记我们想要包含在JSON表示中的字段来定义多个序列化/反序列化上下文。此注解具有Class类型的必需参数,用于区分上下文。
使用@JsonView在我们的类中标记字段时,我们应该记住,默认情况下,序列化上下文包括未明确标记为视图一部分的所有属性。为了覆盖此行为,我们可以禁用DEFAULT_VIEW_INCLUSION映射器功能。
首先,让我们定义一个带有一些内部类的View类,我们将它们用作@JsonView注解的参数:
class View {public static class User {}public static class Admin extends User {}
}
接下来,我们将@JsonView注解添加到我们的类中,使ownerName只能访问admin角色:
@JsonView(View.User.class)
private int id;
@JsonView(View.User.class)
private String name;
@JsonView(View.Admin.class)
private String ownerName;
如何将@JsonView注解与Spring Security 集成
现在,让我们添加一个包含所有角色及其名称的枚举。之后,让我们介绍JSONView和安全角色之间的映射:
enum Role {ROLE_USER,ROLE_ADMIN
}class View {public static final Map<Role, Class> MAPPING = new HashMap<>();static {MAPPING.put(Role.ADMIN, Admin.class);MAPPING.put(Role.USER, User.class);}//...
}
最后,我们来到了整合的中心点。为了绑定JSONView和Spring Security角色,我们需要定义适用于我们应用程序中所有控制器方法的控制器。
到目前为止,我们唯一需要做的就是覆盖AbstractMappingJacksonResponseBodyAdvice类的 beforeBodyWriteInternal方法:
@RestControllerAdvice
class SecurityJsonViewControllerAdvice extends AbstractMappingJacksonResponseBodyAdvice {@Overrideprotected void beforeBodyWriteInternal(MappingJacksonValue bodyContainer,MediaType contentType,MethodParameter returnType,ServerHttpRequest request,ServerHttpResponse response) {if (SecurityContextHolder.getContext().getAuthentication() != null&& SecurityContextHolder.getContext().getAuthentication().getAuthorities() != null) {Collection<? extends GrantedAuthority> authorities= SecurityContextHolder.getContext().getAuthentication().getAuthorities();List<Class> jsonViews = authorities.stream().map(GrantedAuthority::getAuthority).map(AppConfig.Role::valueOf).map(View.MAPPING::get).collect(Collectors.toList());if (jsonViews.size() == 1) {bodyContainer.setSerializationView(jsonViews.get(0));return;}throw new IllegalArgumentException("Ambiguous @JsonView declaration for roles "+ authorities.stream().map(GrantedAuthority::getAuthority).collect(Collectors.joining(",")));}}
}
这样,我们的应用程序的每个响应都将通过这个路由,它将根据我们定义的角色映射找到合适的返回结果。请注意,此方法要求我们在处理具有多个角色的用户时要小心。
基于Spring Security Role过滤Jackson JSON输出内容相关推荐
- 基于Spring Security实现权限管理系统
基于Spring Security实现权限管理系统 稍微复杂一点的后台系统都会涉及到用户权限管理.何谓用户权限?我的理解就是,权限就是对数据(系统的实体类)和数据可进行的操作(增删查改)的集中管理.要 ...
- 基于 Spring Security OAuth2和 JWT 构建保护微服务系统
我们希望自己的微服务能够在用户登录之后才可以访问,而单独给每个微服务单独做用户权限模块就显得很弱了,从复用角度来说是需要重构的,从功能角度来说,也是欠缺的.尤其是前后端完全分离之后,我们的用户信息不一 ...
- java oauth sso 源码_基于Spring Security Oauth2的SSO单点登录+JWT权限控制实践
概 述 在前文<基于Spring Security和 JWT的权限系统设计>之中已经讨论过基于 Spring Security和 JWT的权限系统用法和实践,本文则进一步实践一下基于 Sp ...
- 基于 Spring Security 的开源统一角色访问控制系统 URACS
URACS Java语言开发的统一角色访问控制系统(Unified Role Access Control System),基于Spring Security 3实现的权限控制系统 程序框架版本说明: ...
- 基于Spring Security角色的访问授权示例
Today we will look into spring security role based access and authorization example. However before ...
- 基于Spring Security与JWT实现单点登录
基于RBAC的权限管理 RBAC(Role-Based Access Control):基于角色的访问控制 当前项目中,RBAC具体的表现为: 管理员表:ams_admin 角色表:ams_role ...
- 基于 Spring Security 搭建用户权限系统(二) - 自定义配置
说明 本文的目的是如何基于 Spring Security 去扩展实现一个基本的用户权限模块, 内容会覆盖到 Spring Security 常用的配置. 文中涉及到的业务代码是不完善的, 甚至会存在 ...
- 基于Spring Security的AJAX请求需要登录的解决方案
基于Spring Security的AJAX请求需要登录的解决方案 参考文章: (1)基于Spring Security的AJAX请求需要登录的解决方案 (2)https://www.cnblogs. ...
- 基于Spring Security 的Java SaaS应用的权限管理
1. 概述 权限管理,一般指根据系统设置的安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源.资源包括访问的页面,访问的数据等,这在传统的应用系统中比较常见.本文介绍的则是基于Saas系统 ...
- Eurynome Cloud Athena 基于Spring Security OAuth2 的前后端分离脚手架
Eurynome Cloud Athena 是什么? Eurynome Cloud Athena 是从 Eurynome Cloud 中提取出来的.可以独立运行的.基于OAuth2认证的.前后端分离的 ...
最新文章
- “移花接木”修复E680i系统内部错误
- 《应试捷径-典型考题解析与考点贯通_系统分析师考试》复习重点提示
- HTML5 进阶系列:拖放 API 实现拖放排序
- PHP数组传递给JavaScript以及json_encode的gbk中文乱码的解决
- Clojure:导入lein项目到IntelliJ IDEA
- 当create table as select 遇上大数据
- armbian docker Chrome_一起学docker06-docker网络
- 语音识别免费的api
- [vm] vm安装xp :non-bootable disk 80 解决办法
- 平面广告创意设计4大原则
- tolower c语言,tolower()
- MOS管开关速度相关参数
- w10系统服务器如何创建新用户,win10添加新用户的方法分享
- apple pencil有买的必要吗?便宜的平替电容笔推荐
- java——html
- python如何爬虫股票数据_如何抓取股票数据_用Python抓取新浪的股票数据
- 用go实现linux命令行
- cobalt strike各种beacon的详解(http/https/tcp)
- python对股票的基本面进行分析_python菜鸟学员如何获取沪深股票基本面数据
- 开博尔智能android播放器C3,开博尔C3四核最新固件Android4.4_KIUI7.0_v1.0.4
热门文章
- 第二届“香山杯”网络安全大赛|MISC
- 为羊哥点赞,利用云服务器搭建私人云笔记
- OneNote2016电脑端修改笔记本名称网页端不同步解决办法
- 360全景地图 android,Android-谷歌VR展示360度全景图
- python sleep函数什么意思_python中sleep函数用法实例分析
- 应用概率统计(陈魁)第十一章(回归分析)部分课后答案
- css less使用
- 计算机科学与技术双一流排名,计算机科学与技术学科排行榜(大学名单大全2020版)...
- 【协议森林】IPv6过渡技术之隧道和翻译技术
- 使用cd-hit对核酸序列或氨基酸序列聚类