在本文中,我们将展示如何根据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输出内容相关推荐

  1. 基于Spring Security实现权限管理系统

    基于Spring Security实现权限管理系统 稍微复杂一点的后台系统都会涉及到用户权限管理.何谓用户权限?我的理解就是,权限就是对数据(系统的实体类)和数据可进行的操作(增删查改)的集中管理.要 ...

  2. 基于 Spring Security OAuth2和 JWT 构建保护微服务系统

    我们希望自己的微服务能够在用户登录之后才可以访问,而单独给每个微服务单独做用户权限模块就显得很弱了,从复用角度来说是需要重构的,从功能角度来说,也是欠缺的.尤其是前后端完全分离之后,我们的用户信息不一 ...

  3. java oauth sso 源码_基于Spring Security Oauth2的SSO单点登录+JWT权限控制实践

    概 述 在前文<基于Spring Security和 JWT的权限系统设计>之中已经讨论过基于 Spring Security和 JWT的权限系统用法和实践,本文则进一步实践一下基于 Sp ...

  4. 基于 Spring Security 的开源统一角色访问控制系统 URACS

    URACS Java语言开发的统一角色访问控制系统(Unified Role Access Control System),基于Spring Security 3实现的权限控制系统 程序框架版本说明: ...

  5. 基于Spring Security角色的访问授权示例

    Today we will look into spring security role based access and authorization example. However before ...

  6. 基于Spring Security与JWT实现单点登录

    基于RBAC的权限管理 RBAC(Role-Based Access Control):基于角色的访问控制 当前项目中,RBAC具体的表现为: 管理员表:ams_admin 角色表:ams_role ...

  7. 基于 Spring Security 搭建用户权限系统(二) - 自定义配置

    说明 本文的目的是如何基于 Spring Security 去扩展实现一个基本的用户权限模块, 内容会覆盖到 Spring Security 常用的配置. 文中涉及到的业务代码是不完善的, 甚至会存在 ...

  8. 基于Spring Security的AJAX请求需要登录的解决方案

    基于Spring Security的AJAX请求需要登录的解决方案 参考文章: (1)基于Spring Security的AJAX请求需要登录的解决方案 (2)https://www.cnblogs. ...

  9. 基于Spring Security 的Java SaaS应用的权限管理

    1. 概述 权限管理,一般指根据系统设置的安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源.资源包括访问的页面,访问的数据等,这在传统的应用系统中比较常见.本文介绍的则是基于Saas系统 ...

  10. Eurynome Cloud Athena 基于Spring Security OAuth2 的前后端分离脚手架

    Eurynome Cloud Athena 是什么? Eurynome Cloud Athena 是从 Eurynome Cloud 中提取出来的.可以独立运行的.基于OAuth2认证的.前后端分离的 ...

最新文章

  1. “移花接木”修复E680i系统内部错误
  2. 《应试捷径-典型考题解析与考点贯通_系统分析师考试》复习重点提示
  3. HTML5 进阶系列:拖放 API 实现拖放排序
  4. PHP数组传递给JavaScript以及json_encode的gbk中文乱码的解决
  5. Clojure:导入lein项目到IntelliJ IDEA
  6. 当create table as select 遇上大数据
  7. armbian docker Chrome_一起学docker06-docker网络
  8. 语音识别免费的api
  9. [vm] vm安装xp :non-bootable disk 80 解决办法
  10. 平面广告创意设计4大原则
  11. tolower c语言,tolower()
  12. MOS管开关速度相关参数
  13. w10系统服务器如何创建新用户,win10添加新用户的方法分享
  14. apple pencil有买的必要吗?便宜的平替电容笔推荐
  15. java——html
  16. python如何爬虫股票数据_如何抓取股票数据_用Python抓取新浪的股票数据
  17. 用go实现linux命令行
  18. cobalt strike各种beacon的详解(http/https/tcp)
  19. python对股票的基本面进行分析_python菜鸟学员如何获取沪深股票基本面数据
  20. 开博尔智能android播放器C3,开博尔C3四核最新固件Android4.4_KIUI7.0_v1.0.4

热门文章

  1. 第二届“香山杯”网络安全大赛|MISC
  2. 为羊哥点赞,利用云服务器搭建私人云笔记
  3. OneNote2016电脑端修改笔记本名称网页端不同步解决办法
  4. 360全景地图 android,Android-谷歌VR展示360度全景图
  5. python sleep函数什么意思_python中sleep函数用法实例分析
  6. 应用概率统计(陈魁)第十一章(回归分析)部分课后答案
  7. css less使用
  8. 计算机科学与技术双一流排名,计算机科学与技术学科排行榜(大学名单大全2020版)...
  9. 【协议森林】IPv6过渡技术之隧道和翻译技术
  10. 使用cd-hit对核酸序列或氨基酸序列聚类