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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31864062/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 19:15:53  来源:igfitidea点击:

Fetch Logged In Username in a webapp secured with Keycloak

javajbossejbkeycloak

提问by aksappy

I have secured an enterprise application with Keycloak using standard wildfly based Keycloak adapters. Issue that I am facing is that the rest web services when invoked, needs to know the username that is currently logged in. How do I get the logged in user information from Keycloak?

我已经使用基于标准 Wildfly 的 Keycloak 适配器通过 Keycloak 保护了一个企业应用程序。我面临的问题是其余的 Web 服务在调用时需要知道当前登录的用户名。如何从 Keycloak 获取登录的用户信息?

I tried using SecurityContext, WebListeneretc. But none of them are able to give me the required details.

我试着用SecurityContextWebListener等等,但他们都不是能够给我所需要的细节。

回答by sebplorenz

You get all user information from the security context.

您可以从安全上下文中获取所有用户信息。

Example:

例子:

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 + "\" }";
}

For the security context to be propagated you have to have a security domain configured as described in the: JBoss/Wildfly Adapter configuration

对于要传播的安全上下文,您必须按照以下所述配置安全域: JBoss/Wildfly 适配器配置

回答by user3569718

You may also set the principal-attributeproperty in the keycloak.jsonfile of your web app to preferred_username.

您还可以将Web 应用程序文件中的principal-attribute属性设置keycloak.jsonpreferred_username.

回答by Sergey Sarabun

Need to add standalone.xml next line:

需要在下一行添加standalone.xml:

<principal-attribute>preferred_username</principal-attribute>

Example:

例子:

<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>

回答by Yeroc

In Keycloak 3.4.3 (may also work on earlier versions) I was able to map username to the subtoken claim name. From the Keycloak admin interface this is done under Clients > [your-client] > Mappers > usernameand then enter subin the Token Claim Namefield. This has the advantage of actually changing the contents of the ID tokenreturned by Keycloak rather than adjusting client-side as in the other answer. This is particularly nice when you're using a standard OpenID Connect library rather than an adapter provided by Keycloak.

在 Keycloak 3.4.3(也可能适用于早期版本)中,我能够将用户名映射到sub令牌声明名称。从 Keycloak 管理界面,这是在下面完成的Clients > [your-client] > Mappers > username,然后sub在该Token Claim Name字段中输入。这具有实际更改ID tokenKeycloak 返回的内容的优点,而不是像在其他答案中那样调整客户端。当您使用标准 OpenID Connect 库而不是 Keycloak 提供的适配器时,这特别好。

回答by cabaji99

In my case i was taking the preferred user name from the token like this

在我的情况下,我从这样的令牌中获取首选用户名

keycloakPrincipal.getKeycloakSecurityContext().getToken();
token.getPreferredUsername();

To work i had to go to keycloak and add on my client template the add builtins if not added preferred username came null.

为了工作,我不得不去 keycloak 并在我的客户端模板上添加内置插件,如果没有添加首选用户名则为空。

Check the username on the built ins, client template -> mappers.

检查内置插件上的用户名,客户端模板 -> 映射器。

After that if worked!

之后,如果工作!