【问题标题】:Jwts.builder().setClaims() method converts list to list of LinkedHashMapsJwts.builder().setClaims() 方法将列表转换为 LinkedHashMaps 列表
【发布时间】:2020-09-15 23:57:27
【问题描述】:

我有一个方法尝试从 Jwt 令牌中提取信息以实例化 UserDetails 实例。该方法如下所示:

public UserDetails loadUserByAuthToken(String authToken){
    Claims claims = getClaimsFromToken(authToken);
    return JwtUserFactory.create(
            claims.get(CLAIM_KEY_USER_ID, Long.class),
              ....
            Collection<? extends GrantedAuthority>claims.get(CLAIM_KEY_GRANTED_AUTHORITIES, Collection.class),
    );

尽管将列表值从 CLAIM_KEY_GRANTED_AUTHORITIES 显式转换为 (List&lt;GrantedAuthority&gt;),但它仍会将列表转换为链接的哈希图。

我在这里读到,当类型未定义时,Jackson 会自动将列表转换为链接的哈希图。 Resteasy converting List to LinkedHashMap 该线程是关于resteasy的,但我认为我的代码中正在发生同样的事情。 在这个线程Class cast exception in JWT 中,我读到 Jackson 在从 jwt 令牌中提取数据时也用于确定数据类型。

关键是我声明了一个类型,即List.class。这是我可以给出的具体内容,因为List&lt;GrantedAuthority&gt;.class 会导致编译错误。当我在控制台中记录列表的内容时,它看起来像这样:

[{authority=ROLE_USER}, {authority=ROLE_ADMIN}]

如何防止 Jackson 将 GrantedAuthorityList 隐式转换为 LinkedHashMap 列表并避免类转换异常?

我使用的是 jjwt 版本 0.9.0

<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.0</version> </dependency>

谢谢

编辑:继承 getClaimsFromToken 方法

public Claims getClaimsFromToken(String token) {
    Claims claims;
    try {
        claims = Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
    } catch (Exception e) {
        e.printStackTrace();
        claims = null;
    }
    return claims;
}

【问题讨论】:

    标签: java jwt


    【解决方案1】:

    好吧,在做了更多研究之后,我发现我的情况没有解决方案。根据 Baeldung https://www.baeldung.com/jackson-collection-array jackson 将自定义对象列表转换为 LinkedHashMap 列表。有一种方法可以使用 jackson ObjectMapper 和 TypeReference 来解决这个问题,但这仅在自定义对象具有默认的无参数构造函数时才有效,而我的没有。

    所以我的解决方法是:

    convertListOfLinkedHashMapsToSimpleGrantedAuthorityList(objectMapper.convertValue(claims.get(CLAIM_KEY_GRANTED_AUTHORITIES, ArrayList.class),
                            new TypeReference<List<LinkedHashMap<String, SimpleGrantedAuthority>>>() { }));
    
        private Set<? extends GrantedAuthority> convertListOfLinkedHashMapsToSimpleGrantedAuthorityList(List<LinkedHashMap<String, SimpleGrantedAuthority>> linkedHashMapList){
            return linkedHashMapList.stream().flatMap(linkedHashMap -> linkedHashMap.values().stream()).collect(Collectors.toSet());
        }
    

    希望对大家有所帮助

    【讨论】:

      猜你喜欢
      • 2015-08-13
      • 1970-01-01
      • 2016-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多