Java 在使用KeyClope保护的webapp中获取登录用户名

Java 在使用KeyClope保护的webapp中获取登录用户名,java,jboss,ejb,keycloak,Java,Jboss,Ejb,Keycloak,我已经使用基于标准wildfly的KeyClope适配器保护了一个带有KeyClope的企业应用程序。我面临的问题是,调用rest web服务时,需要知道当前登录的用户名。我如何从keydove获取登录的用户信息 我尝试使用了SecurityContext,WebListener等,但没有一个能够提供所需的详细信息。您可以从安全上下文中获取所有用户信息 例如: public class Greeter { @Context SecurityContext sc; @GET @

我已经使用基于标准wildfly的KeyClope适配器保护了一个带有KeyClope的企业应用程序。我面临的问题是,调用rest web服务时,需要知道当前登录的用户名。我如何从keydove获取登录的用户信息


我尝试使用了
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 + "\" }";
}
<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>
公共类迎宾员{
@上下文
SecurityContext sc;
@得到
@产生(MediaType.APPLICATION_JSON)
公共字符串sayHello(){
//这将用户id设置为用户名
字符串userName=sc.getUserPrincipal().getName();
if(sc.getUserPrincipal()实例的keyDopperPrincipal){
keydoveprincipal kp=(keydoveprincipal)sc.getUserPrincipal();
//这是如何获取真实用户名(或者更确切地说是登录名)
userName=kp.getKeyDopperSecurityContext().getIdToken().getPreferredUsername();
}
返回“{message:\“Hello”+用户名+“\”}”;
}
对于要传播的安全上下文,必须按照中的说明配置安全域:

您还可以将web应用程序的
keydove.json
文件中的
principal属性设置为
preferred\u username
需要添加standalone.xml下一行:

<principal-attribute>preferred_username</principal-attribute>
首选\u用户名
例如:

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

域名
资源名称
真的
https://keycloak-hostname/auth
外部的
首选用户名

在Keyclope 3.4.3(可能也适用于早期版本)中,我能够将用户名映射到
子项
令牌声明名称。从Keyclope管理界面,这是在
客户端>[您的客户端]下完成的>映射器>用户名
,然后在
令牌声明名称
字段中输入
sub
。这样做的好处是,实际上可以更改KeyClope返回的
ID令牌
的内容,而不是像中那样调整客户端。当您使用标准OpenID连接库而不是keydove提供的适配器。

在我的例子中,我从令牌中获取首选用户名,如下所示

keycloakPrincipal.getKeycloakSecurityContext().getToken();
token.getPreferredUsername();
为了工作,我必须转到KeyClope并在我的客户机模板上添加添加内置项,如果没有添加首选用户名,则为空

在内置的客户端模板->映射器上检查用户名


在此之后,如果成功了!

keydeposeprincipal可从keydepose core获得,对于那些不知道它来自何处的人来说,如果出现空指针异常,就像我在使用上述承载令牌时遇到的那样:使用
getToken()
而不是
getIdToken()
谢谢!这是一个比公认的答案好得多的答案,因为如果整个项目打包为EAR,您的答案允许
SessionContext.getCallerPrincipal.getName
在EJB层工作。