动态更改JWT主题字段

时间:2017-08-31 09:19:15

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

我在Web应用程序中成功实现了JWT作为身份验证过滤器。当用户.classname { font-family: 'myfont', Arial, Helvetica, sans-serif; } 成功后,我即会在login的{​​{1}}字段中创建新的JWT并分配userName。 在随后的请求中,我在sub JWT字段中使用userName来标识用户。但是如果用户在应用程序的更新部分中更改了他的JWT该怎么办?有没有办法,我可以在sub中更新userName字段的值?

我在想什么!

我正在考虑在sub中获取现有的JWT,在更新JWT之后,我会再次使用新的RestController更新userName发回给客户。这样很好还是有更好的方法?

2 个答案:

答案 0 :(得分:1)

我认为我应该在更新完成后刷新令牌并将刷新的令牌发送回客户端。

@RequestMapping( value = "/account", method = RequestMethod.POST )
public ResponseEntity<?> updateAccount( @RequestBody UserDetailsBean userDetailsBean, HttpServletRequest request,
        HttpServletResponse response )
{
    try
    {
        UserAccessDetails accessDetails = getLoggedInUser();
        UserDetailsBean updatedUserBean = userService.updateAccount(userDetailsBean, accessDetails);

        // send updated jwt incase of mobile number update by user
        response.addHeader(SecurityConstants.HEADER_STRING,
                SecurityConstants.TOKEN_PREFIX + refreshJWT(updatedUserBean.getMobileNumber()));
        return buildResponse(updatedUserBean);
    }
    catch( DataException e )
    {
        return buildError(e);
    }
}

private String refreshJWT( String subject )
{
    return Jwts.builder().setSubject((subject))
            .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
            .signWith(SignatureAlgorithm.HS512, SecurityConstants.SECRET).compact();
}

这很有效。如果有人有更清洁和行业标准的方法,请说明。

答案 1 :(得分:1)

如果您允许用户更改其用户名,则他们还应具有可变用户ID,该用户ID可用于标识与给定用户关联的任何数据或活动。否则,只要用户更改其名称,您将无法审核用户过去的操作,或者您必须更新数据库中对该用户名的所有引用。更糟糕的是,如果在数据库中引用旧用户名而另一个用户使用该用户名 - 现在由于用户标识处理不正确,现在您有一个用户的数据与另一个用户关联。

现在说,子声明应该包含这个不可变的用户ID。您可以为可变用户名创建单独的声明。当用户名被更改时,您现在只需要更改数据库中的单个字段(假设只有users表引用了这个可变用户名)。然后,您可以使用刷新令牌检索包含最新用户名的新令牌,然后您可以根据需要使用该用户名。

使用这种方法,您应该小心仅将用户名声明用于显示目的,而不是用于识别登录用户,因为它是可变的。包含用户ID的子声明将用于识别用户。

同样重要的是要注意,此解决方案不需要特殊的逻辑来“更新子索赔”。您将使用与已用于生成提供的刷新令牌的令牌相同的逻辑。