【问题标题】:Quarkus JWT authentication doesn't work as a native appQuarkus JWT 身份验证不能用作本机应用程序
【发布时间】:2021-08-30 19:25:04
【问题描述】:

我使用以下命令创建了一个新的 Quarkus 应用:

mvn io.quarkus:quarkus-maven-plugin:1.13.7.Final:create \
    -DprojectGroupId=com.okta.rest \
    -DprojectArtifactId=quarkus \
    -DclassName="com.okta.rest.quarkus.HelloResource" \
    -Dpath="/hello" \
    -Dextensions="smallrye-jwt"

然后,我修改了生成的HelloResource,打印出用户名。

package com.okta.rest.quarkus;

import io.quarkus.security.Authenticated;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.SecurityContext;
import java.security.Principal;

@Path("/hello")
public class HelloResource {

    @GET
    @Path("/")
    @Authenticated
    @Produces(MediaType.TEXT_PLAIN)
    public String hello(@Context SecurityContext context) {
        Principal userPrincipal = context.getUserPrincipal();
        return "Hello, " + userPrincipal.getName() + "!";
    }

}

为了使这项工作与 Okta 一起工作,我向 application.properties 添加了几个属性:

mp.jwt.verify.publickey.location=https://dev-1309757.okta.com/oauth2/default/v1/keys
mp.jwt.verify.issuer=https://dev-1309757.okta.com/oauth2/default

我修复了 HelloResourceTest,所以它现在需要 401。

package com.okta.rest.quarkus;

import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;

@QuarkusTest
public class HelloResourceTest {

    @Test
    public void testHelloEndpoint() {
        given()
          .when().get("/hello")
          .then()
             .statusCode(401);
    }

}

然后,我跑了./mvnw quarkus:dev。我可以使用OIDC Debugger 生成有效的访问令牌并使用 HTTPie 访问此 API。

http :8080/hello Authorization:"Bearer $TOKEN"

回复是:

HTTP/1.1 200 OK
Content-Length: 28
Content-Type: text/plain;charset=UTF-8

Hello, matt.raible@okta.com!

但是,如果我使用 ./mvnw package -Pnative 将其构建为本机映像并尝试运行它,我将无法访问 API。

我不确定在构建时是否需要担心 Unable to get GraalVM version 错误。

[INFO] --- quarkus-maven-plugin:1.13.7.Final:build (default) @ quarkus ---
[INFO] [org.jboss.threads] JBoss Threads version 3.2.0.Final
[INFO] [io.quarkus.deployment.pkg.steps.JarResultBuildStep] Building native image source jar: /Users/mraible/graalvm-java/quarkus/target/quarkus-1.0.0-SNAPSHOT-native-image-source-jar/quarkus-1.0.0-SNAPSHOT-runner.jar
[INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildStep] Building native image from /Users/mraible/graalvm-java/quarkus/target/quarkus-1.0.0-SNAPSHOT-native-image-source-jar/quarkus-1.0.0-SNAPSHOT-runner.jar
[ERROR] [io.quarkus.deployment.pkg.steps.NativeImageBuildStep] Unable to get GraalVM version from the native-image binary.
[INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildRunner] /Users/mraible/.sdkman/candidates/java/21.1.0.r11-grl/bin/native-image ...

运行./target/quarkus-1.0.0-SNAPSHOT-runner 一切正常。

2021-06-14 16:19:10,616 INFO  [io.quarkus] (main) quarkus 1.0.0-SNAPSHOT native (powered by Quarkus 1.13.7.Final) started in 0.020s. Listening on: http://0.0.0.0:8080
2021-06-14 16:19:10,617 INFO  [io.quarkus] (main) Profile prod activated.
2021-06-14 16:19:10,617 INFO  [io.quarkus] (main) Installed features: [cdi, mutiny, resteasy, security, smallrye-context-propagation, smallrye-jwt, vertx, vertx-web]

但是,我无法使用有效的访问令牌访问 /hello 端点。

$ http :8080/hello Authorization:"Bearer $TOKEN"
HTTP/1.1 401 Unauthorized
content-length: 0
www-authenticate: Bearer {token}

如果我停止本机应用程序并运行./mvnw quarkus:dev,同样的命令会起作用。

$ http :8080/hello Authorization:"Bearer $TOKEN"
HTTP/1.1 200 OK
Content-Length: 28
Content-Type: text/plain;charset=UTF-8

Hello, matt.raible@okta.com!

【问题讨论】:

  • 嗨,马特,您能否添加此日志配置:quarkus.io/guides/…
  • 这个测试,github.com/quarkusio/quarkus/blob/main/integration-tests/…,还从远程 JWK 端点获取验证密钥,并在本机模式下运行。 Quarkus JWT 演示也在本机模式下运行,但它使用本地密钥 - 所以还不确定问题出在哪里
  • 我刚刚在本机模式下运行了 Quarkus JWT 快速入门,从 Keycloak 获取密钥,在 OIDC 调试器的帮助下获取令牌,并且所有都适用于 curl。请看一下日志,我想知道那里会显示什么
  • 感谢您提供有关如何打开日志记录的提示。当我这样做时,我看到错误与 HTTPS 有关。 Caused by: java.net.MalformedURLException: Accessing an URL protocol that was not enabled. The URL protocol https is supported but not enabled by default. It must be enabled by adding the --enable-url-protocols=https option to the native-image command.
  • 其他人建议这可能是 SSL 问题,并将我推荐给 quarkus.io/guides/native-and-ssl。似乎一种简单的解决方法是添加诸如 OAuth2 扩展之类的东西。有没有更好的方法来启用 TLS?

标签: quarkus graalvm quarkus-oidc


【解决方案1】:

请启用quarkus-smallrye-jwt TRACE logging 以查看令牌被拒绝的原因。 实际上,正如您还发现的那样,需要在本机映像中启用 https 协议,这可以通过将 <quarkus.native.additional-build-args>--enable-url-protocols=https</quarkus.native.additional-build-args> 添加到 pom.xml 中的本机配置文件的属性中来完成,正如您所展示的 :-) .

This PR 将确保不需要手动添加。

谢谢

【讨论】:

  • 感谢您创建 PR 以添加此内容!很高兴看到它会出现在下一个版本中。 ?
猜你喜欢
  • 2019-10-30
  • 2019-06-30
  • 2015-01-08
  • 1970-01-01
  • 2018-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-19
相关资源
最近更新 更多