获取用户并在vert.x中验证JWT令牌

时间:2017-05-22 07:58:23

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

我已经设置了一个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
}

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

3 个答案:

答案 0 :(得分:3)

如果我理解正确,你有一个API在标题中用JWT发出请求。

在这种情况下,您不应该使用OAuth2处理程序,而是使用J WT handler。此处理程序可与keycloak中的read only tokens一起使用。

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

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

你可以随意检查它。

答案 1 :(得分:0)

你现在这样做会试着自动验证你。
如果您想执行一些手动步骤,请使用authProvider.getToken

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

答案 2 :(得分:0)

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

"public-key": "MypublickeyblablablavOCAQ8AMvdsvseee"