【问题标题】:Get user and validate JWT token in vert.x在 vert.x 中获取用户并验证 JWT 令牌
【发布时间】:2017-10-21 19:11:57
【问题描述】:

我已经建立了一个 keycloak 服务器,并且我正在开发一个将在互联网上发布的 API。 API 将接收第三方(客户端)的调用。这些客户端将首先使用 clientId 和 secret 调用 keycloak 服务器以获取令牌,然后他们将使用此令牌调用我的 API。

我需要看看如何解析和验证这个令牌。此令牌可能是 JWT。 因此,在我的测试用例中,我有一个 HTTP 请求,其标头中有一个 json Web 令牌。令牌由在 localhost 中启动的 keycloak 提供。我已经复制了整个令牌:

{"Authorization":"Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJGSjg2R2NGM2pUYk5MT2NvNE52WmtVQ0lVbWZZQ3FvcXRPUWVNZmJoTmxFIn0.eyJqdGkiOiI2YWZlZjBiMC03ZmQ1LTRiOWUtOTk3NC0yOGFjMzBkMGM5OWQiLCJleHAiOjE0OTU2MTA0NTQsIm5iZiI6MCwiaWF0IjoxNDk1NjEwMTU0LCJpc3MiOiJodHRwOi8vMTI3LjAuMC4xOjgxMDAvYXV0aC9yZWFsbXMvZXhhbXBsZSIsImF1ZCI6ImpzLWNvbnNvbGUiLCJzdWIiOiJjNGY4NjE0Zi02YjFlLTRlYjItYmYxZC0wOTJmNGYxNWQwYmIiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJqcy1jb25zb2xlIiwiYXV0aF90aW1lIjowLCJzZXNzaW9uX3N0YXRlIjoiNTQ4NDJjNTgtMzYxYi00MDk2LThhNjgtNGZkZTg5OGUwNzg5IiwiYWNyIjoiMSIsImNsaWVudF9zZXNzaW9uIjoiNDNjMWEzMjAtNGZmNi00NmRmLThmZjUtNTU2ZjgxNGZhYzk1IiwiYWxsb3dlZC1vcmlnaW5zIjpbXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbInVzZXIiXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJuYW1lIjoiU2FtcGxlIFVzZXIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJ1c2VyIiwiZ2l2ZW5fbmFtZSI6IlNhbXBsZSIsImZhbWlseV9uYW1lIjoiVXNlciIsImVtYWlsIjoic2FtcGxlLXVzZXJAZXhhbXBsZSJ9.n1K0KIGYJYPZkjSq1eSg5gWnCAj44mgl4M-GJOlzgCj8y5TGw5OhT7sr84o9Ja9K6WMW3t0ti6feZIgc8mps3RK0HuuXeCNcrN6H2dPEtBphTvfXEUR2iMg83iCmxjhXgXso7oX2vyreJqB6WCCFEPbAQH2e5kHZqv6cfmXRlYU"}

我想:

  • 解析令牌
  • 获取我需要的键/值对
  • 在 keycloak 服务器中验证令牌。

目标是保护其余服务并授予对特定角色的访问权限。 我的应用程序是带有路由的 3.4.1 vert.x。

我现在有一个我发现的设置 JWTAuthHandler 的示例

    JWTAuth authProvider = JWTAuth.create(vertx, config().getJsonObject("keycloak.oidc"));
    router.route("/protected/*").handler(JWTAuthHandler.create(authProvider));

    router.route("/protected/somepage").handler(ctx -> {
        logger.info("Headers: {}", ctx.request().headers().get("Authorization"));
        logger.info(ctx.user().principal().encodePrettily());
    });

来自我的 API(用于 JWTAuth)的调用的 Keycloak 配置是:

   "keycloak.oidc": {
    "realm": "myrealm",
    "auth-server-url": "http://localhost:8100/auth",
    "ssl-required": "none",
    "resource": "app-client",
    "public-client": true
}

当我在邮递员中进行其余调用时,jvm 并没有真正设法进入处理程序并记录标头,它会立即抛出此异常 说 io.vertx.ext.web.handler.impl.JWTAuthHandlerImpl AVERTISSEMENT: JWT decode failure java.lang.RuntimeException: Not enough or too many segments

【问题讨论】:

  • 您收到的错误是告诉您收到的令牌不是有效的 JWT,因为 JWT 至少需要 2 个段。有关这些部分的详细信息,请参阅:jwt.io,因为它为您提供了有关其工作方式的良好视觉反馈。我猜你得到的不仅仅是 JWT
  • String[] 段数组由 3 个段组成(我处于调试模式)。我还在 jwt.io 上检查过。我不知道它有什么问题。
  • 我需要在通话中添加任何证书或公钥/私钥吗?现在,在我的 API 中,我使用以下客户端配置调用 keycloak:` "keycloak.oidc": { "realm": "myrealm", "auth-server-url": "localhost:8100/auth", "ssl-required" :“无”,“资源”:“应用程序客户端”,“公共客户端”:true }`
  • 配置不正确,我们有一个拉取请求,要求它严格输入,但同时你可以看到这个完全工作的例子:github.com/openshiftio-vertx-boosters/…

标签: java oauth-2.0 openid vert.x keycloak


【解决方案1】:

如果我理解正确,您有一个 API 可以在标头中使用 JWT 发出请求。

在这种情况下,您不应使用 OAuth2 处理程序,而应使用 JWT handler。此处理程序可以与来自 keycloak 的read only tokens 一起使用。

重要的是要知道,与任何其他 Auth 处理程序一样,如果请求通过验证,您将获得一个 User 对象。这个对象可以用来执行authorization assertions。或者,如果您对令牌的原始 JSON 表示感兴趣,您可以将其解读为:

JsonObject token = context.user().principal();

您可以随意检查它。

【讨论】:

  • 我已经建立了一个 keycloak 服务器,我正在开发 API。我会接到第三方的电话。这些第三方将首先调用 keycloak 服务器来获取令牌,然后他们将使用令牌调用我的 API。我需要看看如何解析和验证这个令牌
  • 感谢您的代码,我将代码修改为:JWTAuth authProvider = JWTAuth.create(vertx, config().getJsonObject("keycloak.oidc")); router.route("/protected/*").handler(JWTAuthHandler.create(authProvider)); router.route("/protected/somepage").handler(ctx -> { String theSubject = ctx.user().principal().getString("sub"); String someKey = ctx.user().principal().getString("someKey"); }); ctx.user() 在我的情况下为 null 如上所述,如何获取在标头中找到的 JWT 的解码数据?
  • 我相信你应该提供一个例子来展示你的代码。鉴于您的处理程序已执行,用户不应为 null,因为它应包含令牌的内容。
  • 自从我的发展演变以来,我在帖子中更新了很多内容。请检查一下,不要犹豫回复。我了解到您是 JWTAuth 的开发者,谢谢
【解决方案2】:

您现在的操作方式将尝试自动验证您的身份。
如果您想做一些手动步骤,请使用authProvider.getToken

见官方例子:https://github.com/vert-x3/vertx-auth/blob/master/vertx-auth-oauth2/src/main/java/examples/AuthOAuth2Examples.java#L196

【讨论】:

    【解决方案3】:

    我查看了 JWTAuthProviderImpl 的源代码,我意识到我需要在配置中提供公钥。所以我刚刚将它添加到我的 keycloak 配置中:

    "public-key": "MypublickeyblablablavOCAQ8AMvdsvseee"
    

    【讨论】:

      猜你喜欢
      • 2018-02-24
      • 2019-06-23
      • 2014-10-15
      • 2019-06-02
      • 2017-07-13
      • 2015-11-14
      • 2017-07-27
      • 2019-10-20
      • 2016-01-17
      相关资源
      最近更新 更多