【问题标题】:Spring Framework - Where to parse JWT for custom claim?Spring Framework - 在哪里解析 JWT 以获取自定义声明?
【发布时间】:2017-12-27 02:59:03
【问题描述】:

我创建了一个 Spring JWT 授权应用程序。 JWT 包含一些自定义声明。在资源服务器端,我想知道我应该在哪里解析 JWT 令牌来收集和检查这些声明?我应该在控制器还是在某些过滤器中执行此操作?最佳做法是什么?也许你有一些例子?

【问题讨论】:

  • 您能否详细说明这些自定义声明的目的?默认情况下,Spring Security 查找权限声明,您可以使用角色或其他权限填充它,然后使用 @PreAuthorize 注释保护方法和端点。
  • 我猜,您的 JWT 令牌中的自定义声明必须为您的应用程序所知。理想情况下,它应该是过滤器的一部分,以提取身份验证值并在 Spring Security 上下文中进行设置。 Auth Manager 将从哪里进行检查。正如@punkrocker27ka 所建议的,后来所有事情都可以由 Spring 安全性本身来处理。看看我的想法实现:github.com/deepak-java/jwt-spring-boot
  • @punkrocker27ka 我需要自定义声明来涵盖一些业务逻辑,默认声明是不够的。 Deepak Singh 感谢您的实施,这将对我有所帮助!
  • @KyleAnderson,你怎么知道 Spring 默认查找“authorities”声明?您可以参考来源或示例吗?我尝试了这种方法,但没有奏效。据我所知,Spring Security 只会自动从“范围”声明中提取权限。例如,其他所有内容都应使用“JwtAuthenticationConverter”手动映射。

标签: spring spring-security jwt spring-security-oauth2


【解决方案1】:

您可以使用 Jackson Object Mapper 和 Spring Security 类的组合,即 Jwt、JwtHelper 和 Authentication。您可以使用 Spring Security 的静态上下文对象获取身份验证,然后使用 JwtHelper 解析您收到的令牌。

ObjectMapper objectMapper = new ObjectMapper();
Authentication authentication = 
SecurityContextHolder.getContext().getAuthentication();
Map<String, Object> map = 
objectMapper.convertValue(authentication.getDetails(), Map.class);

// create a token object to represent the token that is in use.
Jwt jwt = JwtHelper.decode((String) map.get("tokenValue"));

// jwt.getClaims() will return a JSON object of all the claims in your token
// Convert claims JSON object into a Map so we can get the value of a field
Map<String, Object> claims = objectMapper.readValue(jwt.getClaims(), Map.class);
String customField = (String) claims.get("you_custom_field_name");

我建议在上面代码的第三行进行调试并设置断点。此时,公开身份验证对象。我可能会提供一些您稍后需要的有用详细信息。

这一切都可以在控制器上完成。我不确定如何使用过滤器来做到这一点。

【讨论】:

  • 这感觉很难看,但它有效(感谢@Chillz)。有一个 PrincipalExtractor 类看起来应该可以使用(只需将自定义实例公开为 Bean),但到目前为止我还无法使其正常工作。
  • JwtHelper 应该在哪个包中?
  • 你在哪里找到JwtHelper类?
  • 使用 Spring Security 5,请改用 JwtDecoders 类。
  • @akuma8 @Frans org.springframework.security.jwt.JwtHelper
【解决方案2】:

你也可以使用springframework.boot.json.JsonParser:

JsonParser parser = JsonParserFactory.getJsonParser();
Map<String, ?> tokenData = parser.parseMap(JwtHelper.decode(token).getClaims());

> tokenData.get("VALID_KEY");

【讨论】:

  • JwtHelper 应该在哪个包中?
【解决方案3】:

我正在使用这个:

private Claim getClaim(String claimKey) {
    Authentication token = SecurityContextHolder.getContext().getAuthentication();
    try {
        DecodedJWT jwt = JWT.decode(token.getCredentials().toString());
        return jwt.getClaim(claimKey);
    } catch (JWTVerificationException ex) {
        throw new RuntimeException(ex);
    }
}

【讨论】:

  • 我能找到的唯一JWTcom.nimbusds.jwt.JWT,这是一个没有decode 方法的接口。请详细说明你的答案?
  • 在我的案例中使用 com.auth0.jwt.JWT 和 com.auth0.jwt.interfaces.DecodedJWT 作为 java-jwt-3.3.0.jar 的一部分
猜你喜欢
  • 2015-09-17
  • 2018-07-05
  • 2016-01-06
  • 2015-03-18
  • 1970-01-01
  • 2019-02-26
  • 1970-01-01
  • 2016-07-05
  • 1970-01-01
相关资源
最近更新 更多