使用 quarkus-oidc 从 SecurityIdentity 访问用户信息

Access user info from SecurityIdentity using quarkus-oidc

我正在使用 quarkus-oidc 和 keycloak,我有以下资源

package graphql;

import io.quarkus.oidc.IdToken;
import io.quarkus.oidc.UserInfo;
import io.quarkus.security.Authenticated;
import io.quarkus.security.identity.SecurityIdentity;
import org.eclipse.microprofile.graphql.Description;
import org.eclipse.microprofile.graphql.GraphQLApi;
import org.eclipse.microprofile.graphql.Query;
import org.eclipse.microprofile.jwt.JsonWebToken;
import javax.inject.Inject;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.SecurityContext;

@GraphQLApi
public class MeResource {

    @Inject
    SecurityIdentity securityIdentity;

    @Query
    @Authenticated
    public User me() {
        return new User(securityIdentity);
    }
}

我的quarkus配置如下

quarkus.oidc.auth-server-url=http://localhost:8080/auth/realms/my-realm
quarkus.oidc.discovery-enabled=true
quarkus.oidc.client-id=my-app
quarkus.oidc.credentials.secret=**********
quarkus.oidc.enabled=true
quarkus.keycloak.policy-enforcer.enable=true
quarkus.http.port=8081

我调用查询如下

curl --request POST \
  --url http://localhost:8081/graphql \
  --header 'authorization: bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICItVFJsRHlFWnB3MGRXRzd4cUZPajl6U2V6aklMTURUaFFkNl9YU0JKYzRJIn0.eyJleHAiOjE2MDI2Mzk2NTEsImlhdCI6MTYwMjYwNDk5MywiYXV0aF90aW1lIjoxNjAyNjAzNzMwLCJqdGkiOiI2NTI4OWZiMC1kNTQ1LTQ3NWQtYmQxZi05Mzk0OTQ1ODk2MGUiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvdm90ZXMiLCJzdWIiOiI1YzhkMGU5OS1jNGY3LTQ3NjctODFjYi0yYjU0ZDdiN2Q0NDUiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJ2b3Rlcy1hcHAiLCJub25jZSI6IiIsInNlc3Npb25fc3RhdGUiOiJiM2Y2NjYyOS1hN2FiLTQ3OWItODFmZS0yOGU0MDI3MDVjMzEiLCJhY3IiOiIwIiwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwibmFtZSI6IkFsYmVydG8gUGVsbGl6em9uIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiYXBlbGxpenoiLCJnaXZlbl9uYW1lIjoiQWxiZXJ0byIsImZhbWlseV9uYW1lIjoiUGVsbGl6em9uIiwiZW1haWwiOiJhbGJlcnRvQG1pa2FtYWkuY29tIn0.hadUk8HzFnn0njk6U5za2N568QTX5w_opR8Vs7ub-hoyAWVND3fjyQJI9mpwKEvqp_ayWHyAcHoGAM16FXnjXKZqNl-iTbpgKNgV9-eMqU7NbR9UokZgGVUUs15cMANlihPiBm7919oG9zkzetNoo7h3ouXwQJwx5nLTIvDJAT-sCgUR5uygY_fEd5W6Jl8Z6kmzrAXKPJP2XSu3pMG0QdWT9Zz0IlW_g91H8bfY0g5OO4cgSuC5pZSu4UiLSKiGK45z_Y-7J-rosItYhIYiJ8v__ZeTeribpKbt14RfuvgVYpqbb6uAgYQkF6ho6sQMhg69sY6RieMG9jM07xCufw' \
  --header 'content-type: application/json' \
  --data '{"query":"query {\n  me {\n    name\n  }\n}"}'

jwt的内容是

{
  "exp": 1602639651,
  "iat": 1602604993,
  "auth_time": 1602603730,
  "jti": "65289fb0-d545-475d-bd1f-93949458960e",
  "iss": "http://localhost:8080/auth/realms/votes",
  "sub": "5c8d0e99-c4f7-4767-81cb-2b54d7b7d445",
  "typ": "Bearer",
  "azp": "votes-app",
  "nonce": "",
  "session_state": "b3f66629-a7ab-479b-81fe-28e402705c31",
  "acr": "0",
  "resource_access": {
    "account": {
      "roles": [
        "manage-account",
        "manage-account-links",
        "view-profile"
      ]
    }
  },
  "scope": "openid profile email",
  "email_verified": true,
  "name": "Alberto Pellizzon",
  "preferred_username": "apellizz",
  "given_name": "Alberto",
  "family_name": "Pellizzon",
  "email": "alberto@mikamai.com"
}

如何使用 quarkus oidc 访问存储在令牌中的用户信息? 我看到有一个选项 quarkus.oidc.authentication.user-info-required=true 将调用 keycloak user-info 端点来解析来自令牌的信息,但它似乎只适用于 keycloak 不提供的不透明令牌!

我不是 Quarkus 专家,但在 the guide for using OpenID 之后,您似乎应该注入 JsonWebToken jwt 以便能够检索与通过 keycloak 验证的特定请求相关的所有信息。

稍后您可以请求令牌中包含的任何数据。 可能你可能需要询问具体的索赔(在你的情况下 "family_name", "given_name", "email", etc) 使用之前的 jwt

它也适用于 JWT 格式的访问令牌,我们有测试证实它