当前位置: 首页 > 知识库问答 >
问题:

Quarkus JWT身份验证不能作为原生应用程序使用

容鸿畴
2023-03-14

我使用以下命令创建了一个新的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"

然后,我修改了生成的< code>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,我在<code>application.properties</code>中添加了几个属性:

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

我修复了< code>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);
    }

}

然后,我运行了./mvnwQuarkus:开发。我能够使用 OIDC 调试器生成有效的访问令牌,并使用 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!

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

我不确定< code > 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]

但是,我无法使用有效的访问令牌访问< code>/helloendpoint。

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

如果我停止本地应用程序并运行<code>/mvnw-quarkus:dev</code>,相同的命令可以工作。

$ 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!

共有1个答案

洪胤
2023-03-14

请启用夸克斯-小黑河-jwt TRACE 日志记录,以查看令牌被拒绝的原因。事实上,正如您还发现的那样,需要在本机映像中启用https协议,这可以通过添加

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

谢啦

 类似资料:
  • 我有一个使用Kafka Streams API的应用程序。我在当地工作时没有问题。我想连接到远程Kafka代理进行阶段测试。远程Kafka代理设置为使用GSSAPI sasl机制并使用Kerberos。我运行用java编写的Streams应用程序时出错。在我查找错误消息后,我找到了答案,但仍然有问题。 错误消息;获取相关id为3的元数据时出错:{[APPID]-KTABLE-AGGREGATE-S

  • 我需要在我们的Web应用程序中使用LDAP/AD服务器实现SSO身份验证和验证用户。Web应用程序是使用Spring(Java)/Hibernate制作的,应用程序服务器是UAT中的Jboss和生产中的Webphere。 我正在寻找一些好的简单的解决方案,可以帮助我实现它,从几个朋友那里听说华夫饼是一个很好的解决方案,但是在网上搜索并尝试了几天之后,我不确定我是否朝着正确的方向前进。我在这方面很幼

  • 问题内容: 我想在我的Java应用程序中使用Windows NTLM认证来透明地认证Intranet用户。如果使用浏览器(单点登录),用户将不会注意到任何身份验证。 我发现了一些具有NTLM支持的库,但是不知道要使用哪个库: http://spnego.sourceforge.net/ http://sourceforge.net/projects/ntlmv2auth/ http://jcifs

  • 我正在尝试使用Facebook凭据实现网站登录。当我在Facebook小部件上按“取消”或“确定”时,我会看到不同的反应。当我按Cancel时,我看到以下内容 这是可预测的。但是当我按OK时,我看到另一个错误。 我在本地运行的网站Ubuntu 14.04 apache Web服务器与80端口。我怀疑错误的Facebook应用程序设置,但不知道调试什么。 此外,我可以提到推特登录也在相同的设置下工作

  • 背景 我想实现本文中提出的设计。 客户端首先使用IDP(OpenID Connect/oauth2)进行身份验证 IDP返回一个访问令牌(不透明的令牌,没有用户信息) 客户端使用授权头中的访问令牌通过API网关进行调用 API网关使用访问令牌向IDP发出请求 IDP验证访问令牌是否有效,并以JSON格式返回用户信息 API网关将用户信息存储在JWT中,并使用私钥对其进行签名。然后将JWT传递给下游

  • 问题内容: 我有一个旧版应用程序,该应用程序通过网络异步接收用户名/密码请求。由于我已经将用户名和密码存储为变量,因此在Linux(Debian 6)上通过PAM进行身份验证的最佳方法是什么? 我尝试编写自己的对话功能,但不确定将密码输入其中的最佳方法。我已经考虑过将其存储在appdata中,并从pam_conv结构中引用它,但是几乎没有关于该操作的文档。 有没有一种简单的方法来对用户进行身份验证