我使用标准的基于Wildfly的Keycloak适配器使用Keycloak获得了企业应用程序。我面临的问题是,其他Web服务在调用时需要知道当前登录的用户名。如何从Keycloak获取登录的用户信息?
我尝试使用SecurityContext
,WebListener
等。但他们都没有能够给我所需的细节。
您可以从安全上下文中获取所有用户信息。
例:
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
您还可以将web应用程序的principal-attribute
文件中的keycloak.json
属性设置为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
下完成的,然后在sub
字段中输入Token Claim Name
。这样做的好处是实际上改变了Keycloak返回的ID token
的内容,而不是像other answer那样调整客户端。当您使用标准的OpenID Connect库而不是Keycloak提供的适配器时,这一点特别好。
在我的情况下,我是从这个令牌中获取首选用户名
keycloakPrincipal.getKeycloakSecurityContext().getToken();
token.getPreferredUsername();
为了工作我必须去keycloak并添加我的客户端模板添加内置如果没有添加首选用户名来null。
检查内置插件,客户端模板 - >映射器上的用户名。
之后如果工作了!