Vertx JWKS / JWT验证抛出500,未记录任何错误

时间:2019-08-18 21:46:33

标签: jwt vert.x

我正在尝试创建一个非常基本的Vertx演示,该演示从端点获取JWK并创建用于验证JWT签名的RSAPublicKey:

package example;

import com.auth0.jwk.JwkException;
import com.auth0.jwk.JwkProvider;
import com.auth0.jwt.interfaces.DecodedJWT;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.core.http.HttpServer;
import io.vertx.ext.web.Router;
import com.auth0.jwk.UrlJwkProvider;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;

import java.net.MalformedURLException;
import java.net.URL;
import java.security.interfaces.RSAPublicKey;
import com.auth0.jwt.interfaces.RSAKeyProvider;
import java.security.interfaces.RSAPrivateKey;


public class MainVerticle extends AbstractVerticle {

  @Override
  public void start(Promise<Void> startPromise) throws Exception {
    HttpServer server = vertx.createHttpServer();
    Router router = Router.router(vertx);

    router.route().handler(routingContext -> {
      String authHeader = routingContext.request().getHeader("Authorization");
      // pull token from header
      String token = authHeader.split(" ")[1];
      URL jwksEndpoint = null;
      try {
        jwksEndpoint = new URL("http://localhost:1080/jwks");
      } catch (MalformedURLException e) {
        e.printStackTrace();
      }

      JwkProvider jwkProvider = new UrlJwkProvider(jwksEndpoint);

      RSAKeyProvider keyProvider = new RSAKeyProvider() {
        @Override
        public RSAPublicKey getPublicKeyById(String kid) {
          //Received 'kid' value might be null if it wasn't defined in the Token's header
          RSAPublicKey publicKey = null;
          try {
            publicKey = (RSAPublicKey) jwkProvider.get(kid).getPublicKey();
          } catch (JwkException e) {
            e.printStackTrace();
          }
          return publicKey;
        }

        @Override
        public RSAPrivateKey getPrivateKey() {
          return null;
        }

        @Override
        public String getPrivateKeyId() {
          return null;
        }
      };

      Algorithm algorithm = Algorithm.RSA256(keyProvider);
      JWTVerifier verifier = JWT.require(algorithm)
        .withIssuer("auth0")
        .build();
      DecodedJWT jwt = verifier.verify(token);
      System.out.println(jwt);

      routingContext.next();
    });

    router.route("/hello").handler(ctx -> {
      ctx.response()
        .putHeader("content-type", "text/html")
        .end("<h1>Hello from non-clustered messenger example!</h1>");
    });

    server.requestHandler(router).listen(8888, http -> {
      if(http.succeeded()) {
        startPromise.complete();
        System.out.println("HTTP server started on port 8888");
      } else {
        startPromise.fail(http.cause());
      }
    });
  }
}

问题是,当我向/ hello端点发出请求时,应用程序立即返回500。但是日志中什么也没有显示(即使在调试级别)。

我尝试手动指定kid属性,以排除jwkProvider无法正常返回

我不知所措,无法对失败的原因有更多的了解。

1 个答案:

答案 0 :(得分:0)

结果完全是我的疏忽。将verifier.verify()调用包裹在try/catch中,向我表明我期待发行人。这是我在Quarkus中尝试实现此目标时遇到的相同问题!我能够从构建器中删除它,现在可以正常使用了。