在使用Keycloak保护的Web应用程序中获取已登录的用户名

21

我使用基于标准wildfly的Keycloak适配器,通过Keycloak保护了企业应用程序。 我遇到的问题是调用rest web服务时需要知道当前已登录用户的用户名。 如何从Keycloak获取已登录用户的信息?

我尝试使用SecurityContextWebListener等方式,但它们都无法提供所需的详细信息。

5个回答

31
你可以从安全上下文中获取所有用户信息。
示例:
public class Greeter {

  @Context
  SecurityContext sc;

  @GET
  @Produces(MediaType.APPLICATION_JSON)
  public String sayHello() {

    // this will set the user id as userName
    String userName = sc.getUserPrincipal().getName();

    if (sc.getUserPrincipal() instanceof KeycloakPrincipal) {
      KeycloakPrincipal<KeycloakSecurityContext> kp = (KeycloakPrincipal<KeycloakSecurityContext>)  sc.getUserPrincipal();

      // this is how to get the real userName (or rather the login name)
      userName = kp.getKeycloakSecurityContext().getIdToken().getPreferredUsername();
    }

    return "{ message : \"Hello " + userName + "\" }";
}

要传播安全上下文,您需要配置一个安全域,如JBoss/Wildfly适配器配置中所述:


5
KeyCloakPrincipal可从keycloak-core获取,对于不知道它来自何处的人来说,这是一个可以使用的信息。 - aksappy
13
遇到像我使用上述令牌时遇到的空指针异常情况:请使用 getToken() 而不是 getIdToken() - devrys

20

您还可以在 Web 应用程序的 keycloak.json 文件中设置 principal-attribute 属性为 preferred_username


3
谢谢!您的回答比被接受的答案更好,因为您的回答允许在将整个项目打包成EAR的情况下,在EJB层使用SessionContext.getCallerPrincipal.getName - j.con

1
需要在下一行添加 standalone.xml:
<principal-attribute>preferred_username</principal-attribute>

例子:

<subsystem xmlns="urn:jboss:domain:keycloak:1.1">
    <secure-deployment name="war-name.war">
        <realm>realm-name</realm>
        <resource>resource-name</resource>
        <public-client>true</public-client>
        <auth-server-url>https://keycloak-hostname/auth</auth-server-url>
        <ssl-required>EXTERNAL</ssl-required>
        <principal-attribute>preferred_username</principal-attribute>
    </secure-deployment>
</subsystem>

1
在我的情况下,我是通过以下方式从令牌中获取首选用户名的。
keycloakPrincipal.getKeycloakSecurityContext().getToken();
token.getPreferredUsername();

为了使工作正常进行,我必须前往Keycloak,并在我的客户端模板上添加内置内容(如果未添加,则首选用户名为空)。

检查内置内容中的用户名,客户端模板 -> 映射器。

之后就可以工作了!


1
在Keycloak 3.4.3中(早期版本也适用),我成功将用户名映射到sub令牌声明名称。从Keycloak管理界面,这可以在Clients > [your-client] > Mappers > username下完成,然后在Token Claim Name字段中输入sub。这样做的优点是实际上更改了由Keycloak返回的ID token的内容,而不是像其他答案那样在客户端进行调整。当您使用标准的OpenID Connect库而不是Keycloak提供的适配器时,这非常方便。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接