如何使用 Keycloak 解码 JWT

Posted

技术标签:

【中文标题】如何使用 Keycloak 解码 JWT【英文标题】:How can i decode JWT using Keycloak 【发布时间】:2018-06-14 22:26:17 【问题描述】:

我在我的应用程序中使用 Keycloak 和 Spring-Boot。我的浏览器客户端请求 keycloak 以生成 JWT,然后将此 JWT 发送到我的 ZUUL 服务器,该服务器使用 keycloak-spring 适配器验证 JWT,然后我编写了一个预过滤器来解码 JWT 有效负载并提取用户名。 我正在使用 com.auth0.java-jwt 库来解码 JWT,如下面的 sn-p

 DecodedJWT dJWT=JWT.decode(header);
 String username=dJWT.getClaim("preferred_username").asString();

我想知道是否无论如何我都可以在不使用外部库的情况下做到这一点。我想使用 keycloak 库显式解码 JWT。我怎样才能做到这一点?

【问题讨论】:

只是好奇,你在 zuul 做这件事有什么原因吗?我想这是你想做的一些请求审计?因为我只有 zuul 来反向代理我感兴趣的服务,所以该服务由 spring-security + keycloak 适配器驱动。弹簧钥匙斗篷适配器自己制作这些东西。 我使用 zuul 作为 API 网关,我在其中进行身份验证/授权和一些请求过滤,如果成功则将请求传递给下游服务。 恕我直言,zuul 不应该为 auth/auth 烦恼。特别是关于授权,因为在我看来与业务逻辑高度耦合,属于您的下游服务。无论如何,对于这种情况,您只需在 zuul 服务中配置 keycloak spring 适配器(因为您使用的是 spring 本身),而不必自己解码 JWT。 我刚刚发现并从 SecurityContextHolder 本身中提取了详细信息。 【参考方案1】:

您必须将 keycloak 的核心库包含到您的依赖项中。 摇篮:compileOnly 'org.keycloak:keycloak-core:3.4.2.Final'

然后使用org.keycloak.TokenVerifier 解析令牌。 示例:

try

  // deprecated: AccessToken token = RSATokenVerifier.create(tokenString).getToken();
  AccessToken token = TokenVerifier.create(tokenString, AccessToken.class).getToken();
  System.out.printf("iss = %s%n", token.getIssuer());
  System.out.printf("sub = %s%n", token.getSubject());
  System.out.printf("typ = %s%n", token.getType());

catch (VerificationException e)

  // some error handling

您还可以通过设置公钥来激活 RSATokenVerifier 上的各种验证,尤其是签名验证:

RSATokenVerifier.create(tokenString).checkActive(true).publicKey(key).verify().getToken()

【讨论】:

'e.printStackTrace();'是个坏主意 RSATokenVerifier 已弃用,应使用 TokenVerifier,代码为:AccessToken token = TokenVerifier.create(tokenString, AccessToken.class).getToken();【参考方案2】:

当我使用 keycloak 对 jwt 进行身份验证时,它会解码 jwt 并将详细信息放入 SecurityContextHolder 中,我只是从那里自行提取详细信息。这是代码。

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    if (authentication != null) 
        if (authentication.getPrincipal() instanceof KeycloakPrincipal) 
            KeycloakPrincipal<KeycloakSecurityContext> kp = (KeycloakPrincipal<KeycloakSecurityContext>) authentication.getPrincipal();
            // retrieving username here
            String username = kp.getKeycloakSecurityContext().getToken().getPreferredUsername();
            
      

这为我解决了。

【讨论】:

以上是关于如何使用 Keycloak 解码 JWT的主要内容,如果未能解决你的问题,请参考以下文章

如何验证在 jwt.io 上使用 Keycloak 身份验证提供程序创建的 HS256 签名 JWT 令牌

如何使用 java 验证由 keycloak 签名的 JWT

使用带有spring security的keycloak JWT令牌时如何修复403

如何配置 Thorntail 2.5.0.Final 以使用来自 Keycloak 的 JWT 令牌授权用户?

如何在 KeyCloak 中的签名 JWT 中获取 client_assertion

http://jwt.io 如何检索 keycloak 签名密钥?