【问题标题】:Injected JsonWebToken is empty with MicroProfile JWT Auth 1.1 on Payara 5.183Payara 5.183 上的 MicroProfile JWT Auth 1.1 注入的 JsonWebToken 为空
【发布时间】:2019-01-04 19:15:55
【问题描述】:

我在使用在 Payara 5.183 上运行的 MicroProfile 2.0.1 后端解码/使用/验证传递给我的 Java EE 8 的 JWT 时遇到问题。 React 前端应用程序将从 Keycloak 获得的 JWT 令牌作为Authorization: Bearer eyXJS... 传递到后端:

mp.jwt.verify.publickey.location=/META-INF/orange.pem
mp.jwt.verify.issuer=http://localhost:8282/auth/realms/MicroProfile

Keycloak 的公钥存储在orange.pem 文件中。 JAX-RS 配置如下所示:

@LoginConfig(authMethod = "MP-JWT")
@ApplicationPath("resources")
public class JAXRSConfiguration extends Application {

}

我正在尝试在其中一个端点中使用 JWT:

@Path("secure")
@Stateless
public class VerySecureResource {

    @Inject
    @ConfigProperty(name = "message")
    private String message;

    @Inject
    private JsonWebToken callerPrincipal;

    @GET
    public Response message() {

        System.out.println(callerPrincipal.getIssuer());
        System.out.println(callerPrincipal.getRawToken());
        System.out.println(callerPrincipal.getTokenID());

        return Response.ok(callerPrincipal.getName() + " is allowed to read message: " + message).build();
    }

}

应用程序部署没有任何错误,我在 Payara 的 server.log 中没有收到任何有关 JWT 验证失败的日志信息。我什至打开了fish.payara.microprofile.jwtauth 的日志记录。

[2018-12-26T17:06:20.835+0100] [Payara 5.183] [INFORMATION] [] [org.glassfish.soteria.servlet.SamRegistrationInstaller] [tid: _ThreadID=196 _ThreadName=admin-thread-pool::admin-listener(6)] [timeMillis: 1545840380835] [levelValue: 800] [[
  Initializing Soteria 1.1-b01 for context '/microprofile-jwt-keycloak-auth']]

[2018-12-26T17:06:20.841+0100] [Payara 5.183] [INFORMATION] [] [fish.payara.microprofile.jwtauth.servlet.RolesDeclarationInitializer] [tid: _ThreadID=196 _ThreadName=admin-thread-pool::admin-listener(6)] [timeMillis: 1545840380841] [levelValue: 800] [[
  Initializing MP-JWT 5.183 for context '/microprofile-jwt-keycloak-auth']]

[2018-12-26T17:06:20.933+0100] [Payara 5.183] [INFORMATION] [AS-WEB-GLUE-00172] [javax.enterprise.web] [tid: _ThreadID=196 _ThreadName=admin-thread-pool::admin-listener(6)] [timeMillis: 1545840380933] [levelValue: 800] [[
  Loading application [microprofile-jwt-keycloak-auth] at [/microprofile-jwt-keycloak-auth]]]

[2018-12-26T17:06:20.949+0100] [Payara 5.183] [INFORMATION] [] [javax.enterprise.system.core] [tid: _ThreadID=196 _ThreadName=admin-thread-pool::admin-listener(6)] [timeMillis: 1545840380949] [levelValue: 800] [[
  microprofile-jwt-keycloak-auth was successfully deployed in 954 milliseconds.]]

[2018-12-26T17:06:26.428+0100] [Payara 5.183] [INFORMATION] [] [] [tid: _ThreadID=42 _ThreadName=http-thread-pool::http-listener-1(3)] [timeMillis: 1545840386428] [levelValue: 800] [[
  null]]

[2018-12-26T17:06:26.428+0100] [Payara 5.183] [INFORMATION] [] [] [tid: _ThreadID=42 _ThreadName=http-thread-pool::http-listener-1(3)] [timeMillis: 1545840386428] [levelValue: 800] [[
  null]]

[2018-12-26T17:06:26.428+0100] [Payara 5.183] [INFORMATION] [] [] [tid: _ThreadID=42 _ThreadName=http-thread-pool::http-listener-1(3)] [timeMillis: 1545840386428] [levelValue: 800] [[
  null]]

解码后的 JWT 如下所示:

{
    "jti": "5a3c600e-95ea-41cb-8e65-8342a3b867bc",
    "exp": 1545840603,
    "nbf": 0,
    "iat": 1545840303,
    "iss": "http://localhost:8282/auth/realms/MicroProfile",
    "aud": "account",
    "sub": "f2a492cb-cf9f-46ac-8f04-941601c6574b",
    "typ": "Bearer",
    "azp": "react-webapp",
    "nonce": "f650eb68-611f-4bd9-97a7-d07f1b3e29de",
    "auth_time": 1545840302,
    "session_state": "f6627b25-b089-4234-b25c-bffa67a9a8f7",
    "acr": "1",
    "allowed-origins": [
        "http://localhost:3000"
    ],
    "realm_access": {
        "roles": [
            "offline_access",
            "uma_authorization",
            "USER"
        ]
    },
    "resource_access": {
        "account": {
            "roles": [
                "manage-account",
                "manage-account-links",
                "view-profile"
            ]
        }
    },
    "scope": "openid profile email",
    "email_verified": false,
    "name": "duke duke",
    "groups": [
        "/USER"
    ],
    "preferred_username": "duke",
    "given_name": "duke",
    "family_name": "duke",
    "email": "duke@jakarta.ee"
}

整个代码库可在GitHub 上获得

【问题讨论】:

  • 您能指出您将 KeyCloak 中的哪个公钥放入了 orange.pem。它是领域的 RSA 密钥的公钥吗?您能否在标头中验证 keyId 是否与领域中定义的 RSA 密钥的 id 匹配。 (并且您在令牌配置的签名算法中指定了 RSA256)
  • 是的,我用 jwt.io 验证了 RSA 签名,这是我领域的公钥
  • 返回什么 HTTP 状态? 401、403、200?
  • 如果 JAX-RS 端点是安全的,我会得到 401

标签: java jwt keycloak payara microprofile


【解决方案1】:

我看到您刚刚在 JAX-RS 应用程序上添加了@LoginConf 注解,但这还不足以保护资源。

这是一种标记,所有受保护的端点都将使用来自 Authentication 标头的 JWT。

所以你需要将端点定义为

@GET
@RolesAllowed("/USER")
public Response message() {

只有这样来自 JWT 的身份验证才会启动。

您需要在 web.xml 中声明所有角色,或者使用 DeclaresRoles 在 Application bean(或任何其他 CDI bean)上声明

@ApplicationPath("/data")
@LoginConfig(authMethod = "MP-JWT")
@DeclareRoles({"/USER"})
public class Keycloack_jwtRestApplication extends Application {

【讨论】:

  • 我想知道@LoginConfig(authMethod = "MP-JWT")这行是否还需要?即,您能否利用 JsonWebToken@RolesAllowed 但不使用 @LoginConfig
  • 当前版本的 MicroProfile JWT 规范仍然需要使用@LoginConfig(authMethod = "MP-JWT")
猜你喜欢
  • 2016-03-13
  • 2021-08-12
  • 2021-05-07
  • 2016-09-02
  • 2018-10-06
  • 2020-09-28
  • 1970-01-01
  • 2020-05-09
  • 1970-01-01
相关资源
最近更新 更多