【问题标题】:Retrieve Keycloak user data using received access token使用接收到的访问令牌检索 Keycloak 用户数据
【发布时间】:2019-02-14 17:52:44
【问题描述】:

我正在开发一个 WildFly 后端(用 Java 编写),它接受 HTTP 请求(来自自定义前端),这些请求通过“授权”HTTP 标头使用用户的 Keycloak 不记名访问令牌进行签名。

后端连接本身已经使用 WildFly 的 Keycloak 适配器进行保护,但在内部,我想检查用户是谁(用户组、名称等)并返回非常好的响应。

我认为可以只从前端发送这些数据,但人们一旦拥有访问令牌就可以轻松伪造请求。有没有办法在只有访问令牌的情况下检索用户数据之类的东西?

【问题讨论】:

    标签: java authentication wildfly keycloak


    【解决方案1】:

    我已经想出了如何解决这个问题!

    首先,在类的顶部附近添加以下内容:

    @Context
    javax.ws.rs.core.SecurityContext securityContext;
    

    这将被注入服务器安全的上下文。要使用 Keycloak,WildFly 需要安装 Wildfly 适配器,并且 web.xml 必须配置为使用 Keycloak。

    在我们继续之前,我们需要 Keycloak-Core 库,例如每个 Maven:

    <!-- https://mvnrepository.com/artifact/org.keycloak/keycloak-core -->
    <dependency>
        <groupId>org.keycloak</groupId>
        <artifactId>keycloak-core</artifactId>
        <version>4.4.0.Final</version>
    </dependency>
    

    4.4.0.Final 是撰写此答案时的最新版本;建议使用最新版本或与 Keycloak 服务器匹配的版本。

    接下来,在您要检索用户信息的地方,检索 UserPrincipal:

    if (securityContext != null && securityContext.getUserPrincipal() instanceof KeycloakPrincipal) {
        KeycloakPrincipal principal = ((KeycloakPrincipal) securityContext.getUserPrincipal());
    

    额外的检查是故障保存,因此可以单独处理非 Keycloak 配置。

    从已转换的 KeycloakPrinciple 中检索 KeycloakSecurityContext 并从那里检索用户的 Token:

    AccessToken token = principal.getKeycloakSecurityContext().getToken();
    

    在某些情况下(取决于您的 Keycloak 和/或 WildFly 的版本),getToken() 可能会返回 null。在这些情况下,请使用 getIdToken():

    IDToken token = principal.getKeycloakSecurityContext().getIdToken();
    

    AccessToken 扩展了 IDToken,因此您在这两种情况下都拥有完整的功能(针对此上下文)。

    可以从令牌中提取所有用户数据。例如,我们获取用户的用户名。在 Keycloak 中,此属性称为“首选用户名”。

    String user = token.getPreferredUsername();
    

    你就完成了!您的完整代码现在可能如下所示:

    if (securityContext != null && securityContext.getUserPrincipal() instanceof KeycloakPrincipal) {
        KeycloakPrincipal principal = ((KeycloakPrincipal) securityContext.getUserPrincipal());
        AccessToken token = principal.getKeycloakSecurityContext().getToken();
        // IDToken token = principal.getKeycloakSecurityContext().getIdToken();
    
        System.out.println("User logged in: " + token.getPreferredUsername());
    } else {
        System.out.println("SecurityContext could not provide a Keycloak context.");
    }
    

    【讨论】:

    • 我们应该为这些导入什么... @Context SecurityContext securityContext;
    猜你喜欢
    • 2018-07-03
    • 2021-04-19
    • 2017-11-15
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 2018-07-27
    • 2017-11-12
    • 1970-01-01
    相关资源
    最近更新 更多