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

Java 在vert.x中获取用户并验证JWT令牌,java,oauth-2.0,openid,vert.x,keycloak,Java,Oauth 2.0,Openid,Vert.x,Keycloak,我已经建立了一个keydape服务器,我正在开发一个API,它将在互联网上发布。API将接收第三方(客户端)的调用。这些客户端将首先使用clientId和secret调用keydape服务器以获取令牌,然后使用该令牌调用我的API 我需要看看如何解析和验证这个令牌。此令牌可能是JWT。 因此,在我的测试用例中,我有一个http请求,在头中有一个json web令牌。令牌由在localhost中启动的KeyClope提供。我复制了整个令牌: {"Authorization":"Bearer eyJ

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

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

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

  • 解析令牌
  • 获取我需要的键/值对
  • 验证KeyClope服务器中的令牌
目标是保护rest服务并授予对特定角色的访问权。 我的应用程序是一个带路由的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());
    });
my API(用于JWTAuth)调用的KeyClope配置为:

当我在postman中进行rest调用时,jvm并没有真正设法进入处理程序并记录头,但它会立即抛出此异常 说
io.vertx.ext.web.handler.impl.JWTAuthHandlerImpl

避免:JWT解码失败java.lang.RuntimeException:段数不足或太多

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


请参阅官方示例:

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

在这种情况下,您不应该使用OAuth2处理程序,而应该使用J。这个处理程序可以与fromKeyClope一起使用

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


JsonObject标记=context.user().principal();


在那里,您可以随意查看。

我查看了JWTAuthProviderImpl的源代码,意识到我需要在配置中提供公钥。因此,我刚刚将其添加到我的KeyClope配置中:

"public-key": "MypublickeyblablablavOCAQ8AMvdsvseee"

我已经建立了一个keybeave服务器,我正在开发API。我会接到第三方的电话。这些第三方将首先调用KeyClope服务器以获取令牌,然后使用令牌调用我的API。我需要看看如何解析和验证这个令牌多亏了您的代码,我将代码修改为:
JWTAuth authProvider=JWTAuth.create(vertx,config().getJsonObject(“keydape.oidc”);route.route(“/protected/*”)处理程序(JWTAuthHandler.create(authProvider));route.route(“/protected/somepage”).handler(ctx->{String theSubject=ctx.user().principal().getString(“sub”);String someKey=ctx.user().principal().getString(“someKey”);})
ctx.user()在我的例子中为空。我如何获得我上面提到的头中找到的JWT的解码数据?我相信您应该提供一个显示代码的示例。假设您的处理程序被执行,那么用户不应该为null,因为它应该包含令牌的内容。请检查一下,不要犹豫回复。我知道您是JWTAuth的开发者,谢谢您收到的错误是您收到的令牌不是有效的JWT,因为JWT至少需要2段。有关这些部分的详细信息,请参见:因为它为您提供了有关其工作方式的良好视觉反馈。我猜您得到的不是JWT字符串[]段数组,它由3段组成(我处于调试模式)。我也在jwt.io上检查过。我不知道有什么问题。我是否需要向呼叫添加任何证书或公钥/私钥?现在,在我的API中,我使用以下客户端配置调用KeyClope:`“KeyClope.oidc”:{“realm”:“myrealm”,“auth server url”:“ssl required”:“none”,“resource”:“app client”,“public client”:true}`配置不正确,我们有一个pull请求,使其严格类型化,但同时您可以看到这个完全有效的示例:
"public-key": "MypublickeyblablablavOCAQ8AMvdsvseee"