在使用 Keycloak 保护的网络应用程序中获取登录用户名
Fetch Logged In Username in a webapp secured with Keycloak
我已经使用基于 wildfly 的标准 Keycloak 适配器通过 Keycloak 保护了一个企业应用程序。我面临的问题是调用其余 Web 服务时需要知道当前登录的用户名。如何从 Keycloak 获取登录用户信息?
我尝试使用 SecurityContext
、 WebListener
等。但是 none 能够提供所需的详细信息。
您从安全上下文中获取所有用户信息。
示例:
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 Adapter configuration
您还可以将网络应用 keycloak.json
文件中的 principal-attribute
属性 设置为 preferred_username
。
下一行需要添加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>
在 Keycloak 3.4.3(也可能适用于早期版本)中,我能够将用户名映射到 sub
令牌声明名称。在 Keycloak 管理界面中,这是在 Clients > [your-client] > Mappers > username
下完成的,然后在 Token Claim Name
字段中输入 sub
。这具有实际更改 Keycloak 返回的 ID token
内容的优势,而不是像 中那样调整客户端。当您使用标准的 OpenID Connect 库而不是 Keycloak 提供的适配器时,这特别好。
在我的例子中,我像这样从令牌中获取首选用户名
keycloakPrincipal.getKeycloakSecurityContext().getToken();
token.getPreferredUsername();
为了工作,我必须去 keycloak 并在我的客户端模板上添加内置函数,如果没有添加首选用户名则为空。
检查内置插件、客户端模板 -> 映射器上的用户名。
之后如果成功了!
我已经使用基于 wildfly 的标准 Keycloak 适配器通过 Keycloak 保护了一个企业应用程序。我面临的问题是调用其余 Web 服务时需要知道当前登录的用户名。如何从 Keycloak 获取登录用户信息?
我尝试使用 SecurityContext
、 WebListener
等。但是 none 能够提供所需的详细信息。
您从安全上下文中获取所有用户信息。
示例:
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 Adapter configuration
您还可以将网络应用 keycloak.json
文件中的 principal-attribute
属性 设置为 preferred_username
。
下一行需要添加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>
在 Keycloak 3.4.3(也可能适用于早期版本)中,我能够将用户名映射到 sub
令牌声明名称。在 Keycloak 管理界面中,这是在 Clients > [your-client] > Mappers > username
下完成的,然后在 Token Claim Name
字段中输入 sub
。这具有实际更改 Keycloak 返回的 ID token
内容的优势,而不是像
在我的例子中,我像这样从令牌中获取首选用户名
keycloakPrincipal.getKeycloakSecurityContext().getToken();
token.getPreferredUsername();
为了工作,我必须去 keycloak 并在我的客户端模板上添加内置函数,如果没有添加首选用户名则为空。
检查内置插件、客户端模板 -> 映射器上的用户名。
之后如果成功了!