我在使用jose4j从JWT访问嵌套声明时遇到问题。我有一个JWT,它的索赔集看起来像这样:
{
"iss": "awesome.issuer",
"iat": 1300819370,
"exp": 1300819380,
"clm": "string claim",
"sub": "batman",
"context": {
"username": "mpdavis",
"firstName": "Michael",
"lastName": "Davis
}
}
当我尝试访问和context
声明中的嵌套声明时,我遇到了问题。我可以使用getClaimValue
轻松访问顶级索赔。
private String qsh;
qsh = jwtClaims.getClaimValue("qsh", String.class);
如果我想得到一个嵌套的索赔,我似乎有两个选择。
第一个选项是找到一种方法,将context
声明作为Map<String,Object>
返回,并从该对象中提取每个声明。另一种选择是使用flattenClaims
将所有声明展平为Map<String,List<Object>>
,并从嵌套声明的映射中获取第一个对象。
如果授予这些JWT的服务极大地改变了模式,那么这两种选项似乎都没有特别的弹性。
有更好的方法吗?
这差不多是对的。
您可以将声明值作为Map获取,并像这样访问其内容(或对其进行迭代)。
@SuppressWarnings("unchecked")
Map<String,String> context = claims.getClaimValue("context", Map.class);
String username = context.get("username");
String firstName = context.get("firstName");
使用flattenClaims
可能看起来像这样:
Map<String,List<Object>> flattened = claims.flattenClaims();
String username = (String)flattened.get("context.username").iterator().next();
String firstName = (String)flattened.get("context.firstName").iterator().next();
或者,您可以迭代整个过程,并将其转换为对应用程序有意义的任何数据结构。
使用isClaimValueOfType(...)
和hasClaim(...)
以及JwtClaims
上的类似内容,您可能会使声明JSON中的更改更有弹性。
或者,如果需要,您也可以在JwtClaims
上使用getRawJson()
,并将JSON传递给您选择的JSON处理器。