从 SecurityIdentity 中使用 Quarkus OIDC 访问用户信息

huangapple go评论119阅读模式
英文:

Access user info from SecurityIdentity using quarkus-oidc

问题

我正在使用带有 Keycloak 的 Quarkus OIDC,以下是我的资源代码:

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 访问存储在令牌中

英文:

I am using quarkus-oidc with keycloak and I have the following resource

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);
    }
}

My quarkus configurations is the following

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

I am calling the query as follow

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}"}'

The content of the jwt is

{
  "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"
}

How can I access the user info stored in the token using quarkus oidc?
I' have seen that there is an option
quarkus.oidc.authentication.user-info-required=true which will be calling the keycloak user-info endpoint to resolve the info from the token but it seems it is only working for opaque tokens which keycloak does not provide!

答案1

得分: 2

我对Quarkus不是专家,但根据使用OpenID的指南,似乎您应该注入JsonWebToken jwt以能够检索与通过Keycloak进行身份验证的特定请求相关的所有信息。

稍后,您可以查询令牌中包含的任何数据。
可能您需要使用先前的jwt来请求特定声明(在您的情况下为“family_name”,“given_name”,“email”等)。

英文:

I'm not an expert on Quarkus, but following the guide for using OpenID it seems that you should inject the JsonWebToken jwt to be able to retrieve all the information related to a particular request authenticated via keycloak.

Later you can ask for any of the data included in the token.
Probably you may need to ask for specific claims (in your case "family_name", "given_name", "email", etc) using the previous jwt

答案2

得分: 0

这也适用于JWT格式中的访问令牌,我们有确认其有效性的测试。

英文:

It also works for the access tokens in a JWT formats, we have tests confirming it

huangapple
  • 本文由 发表于 2020年10月14日 00:48:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/64339661.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定