写点什么

[Pulsar] JWT 认证的原理

作者:Zike Yang
  • 2021 年 12 月 03 日
  • 本文字数:1345 字

    阅读完需:约 4 分钟

https://xie.infoq.cn/article/8a1479d397211606e5223f3e5中我们介绍了如何设置 JWT 认证,本文将介绍 Pulsar 的 JWT 认证的原理。


Pulsar 的认证 Provider 都需要实现 AuthenticationProvider 的接口,JWT 认证使用的是 AuthenticationProviderToken 进行实现。初始化的时候,会创建一个 Jwt Parser,用于后续的 token 解析。

this.parser = Jwts.parserBuilder().setSigningKey(this.validationKey).build();
复制代码

而其中所使用的 validationKey,则是使用用户所设置的密钥以及加密算法生成的。

当需要进行认证的时候,Broker 会调用 AuthenticationProviderToken 的 authenticate 方法,这个方法会返回 token 所解析并认证的 role,如果认证失败则会抛出 AuthenticationException,如下。

@Overridepublic String authenticate(AuthenticationDataSource authData) throws AuthenticationException {    try {        // Get Token        String token;        token = getToken(authData);        // Parse Token by validating        String role = getPrincipal(authenticateToken(token));        AuthenticationMetrics.authenticateSuccess(getClass().getSimpleName(), getAuthMethodName());        return role;    } catch (AuthenticationException exception) {        AuthenticationMetrics.authenticateFailure(getClass().getSimpleName(), getAuthMethodName(), exception.getMessage());        throw exception;    }}
复制代码


在 Broker 调用认证方法时,会传入认证所需要的参数 AuthenticationDataSource,通过这个 authData,可以得到 token 的信息。authData 中有两种存储 token 的方式,如果是使用 binary protocol 协议的形式,如使用 Java client 或 pulsar client tool 进行访问认证,则会将 token 存储到 authData 中的 command data 中;而如果使用 http/https 协议,如使用 pulsar admin 进行访问认证,则会将 token 存储到 authData 中的 http data 的 header "Authorization"中,与 Web 的 JWT 认证一样,其 token 前会带有 Bearer 的前缀。


第二步就是对 token 进行认证,调用 authenticateToken 的方法,内部主要是调用 parser 进行解析认证。

Jwt<?, Claims> jwt = parser.parseClaimsJws(token);
复制代码

当认证失败,如 token 过期等问题,则会抛出 JwtException 的异常,成功则返回解析出来的 Jwt 结构。


最后一步就是根据上一步所得到的 Jwt 结构,得到其中的 principal,也就是用户所使用的角色。调用的是 getPrincipal 方法。

private String getPrincipal(Jwt<?, Claims> jwt) {    try {        return jwt.getBody().get(roleClaim, String.class);    } catch (RequiredTypeException requiredTypeException) {        List list = jwt.getBody().get(roleClaim, List.class);        if (list != null && !list.isEmpty() && list.get(0) instanceof String) {            return (String) list.get(0);        }        return null;    }}
复制代码

这里支持两种类型的 role,一种是字符串类型的,一种是数组类型的。用户可以通过 tokenAuthClaim 设置所使用的 role 的字段。对于数组类型的 roles,则会返回第一个作为 role,用于后续的鉴权。


至此,整个 JWT 认证就完成了,后续 Broker 将会利用所得到的角色,用于鉴权,最终再进行各类的资源访问和操作。

发布于: 刚刚阅读数: 3
用户头像

Zike Yang

关注

还未添加个人签名 2020.10.20 加入

Apache Pulsar Contributor

评论

发布
暂无评论
[Pulsar] JWT认证的原理