资讯专栏INFORMATION COLUMN

基于Spring Security Role过滤Jackson JSON输出内容

zhangyucha0 / 3174人阅读

摘要:在本文中,我们将展示如何根据中定义的用户角色过滤序列化输出。请注意,此方法要求我们在处理具有多个角色的用户时要小心。

在本文中,我们将展示如何根据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 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 {
 
    @Override
    protected void beforeBodyWriteInternal(
      MappingJacksonValue bodyContainer,
      MediaType contentType,
      MethodParameter returnType,
      ServerHttpRequest request,
      ServerHttpResponse response) {
        if (SecurityContextHolder.getContext().getAuthentication() != null
          && SecurityContextHolder.getContext().getAuthentication().getAuthorities() != null) {
            Collection authorities
              = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
            List 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(",")));
        }
    }
}

这样,我们的应用程序的每个响应都将通过这个路由,它将根据我们定义的角色映射找到合适的返回结果。请注意,此方法要求我们在处理具有多个角色的用户时要小心

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73276.html

相关文章

  • springSecurity02(mybatis+springmvc+spring) 01

    摘要:建立一个模块继承上一个模块然后添加依赖解决打包时找不到文件建立数据源文件数据库连接相关修改配置数据源和整合,以及事务管理自动扫描扫描时跳过注解的类控制器扫描配置文件这里指向的是 1.建立一个模块继承上一个模块然后添加依赖 junit junit 4.11 test ...

    FrancisSoung 评论0 收藏0
  • 使用JWT保护你的Spring Boot应用 - Spring Security实战

    摘要:创建应用有很多方法去创建项目,官方也推荐用在线项目创建工具可以方便选择你要用的组件,命令行工具当然也可以。对于开发人员最大的好处在于可以对应用进行自动配置。 使用JWT保护你的Spring Boot应用 - Spring Security实战 作者 freewolf 原创文章转载请标明出处 关键词 Spring Boot、OAuth 2.0、JWT、Spring Security、SS...

    wemall 评论0 收藏0
  • SpringSecurity01(使用传统的xml方式开发,且不连接数据库)

    摘要:创建一个工程在里面添加依赖,依赖不要随便改我改了出错了好几次都找不到原因可以轻松的将对象转换成对象和文档同样也可以将转换成对象和配置 1.创建一个web工程2.在pom里面添加依赖,依赖不要随便改,我改了出错了好几次都找不到原因 UTF-8 1.7 1.7 2.5.0 1.2 3.0-alpha-1 ...

    Gilbertat 评论0 收藏0
  • 基于 Spring Session & Spring Security 微服务权限控制

    摘要:构造函数的第一个参数是对象,所以可以自定义缓存对象。在微服务各个模块获取用户的这些信息的方法如下略权限控制启用基于方法的权限注解简单权限校验例如,删除角色的接口,仅允许拥有权限的用户访问。 showImg(https://segmentfault.com/img/remote/1460000019593311); 微服务架构 showImg(https://segmentfault.c...

    clasnake 评论0 收藏0
  • 关于web.xml配置的那些事儿

    摘要:的版本增加了对事件监听程序的支持,事件监听程序在建立修改和删除会话或环境时得到通知。元素指出事件监听程序类。过滤器配置将一个名字与一个实现接口的类相关联。 1.简介 web.xml文件是Java web项目中的一个配置文件,主要用于配置欢迎页、Filter、Listener、Servlet等,但并不是必须的,一个java web项目没有web.xml文件照样能跑起来。Tomcat容器/...

    zhichangterry 评论0 收藏0

发表评论

0条评论

zhangyucha0

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<