我很难在Keycloak 6.0.1中使用一个非常简单的Keycloak ProtocolMapper。
我正在尝试为访问令牌添加额外的声明。当我将生成的jar复制到部署目录时,在部署目录中获得以下NullPointerException,并在.failed文件中包含以下内容。
{"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"token-enhancer-1.0-SNAPSHOT.jar\".POST_MODULE" => "WFLYSRV0153: Failed to process phase POST_MODULE of deployment \"token-enhancer-1.0-SNAPSHOT.jar\"
Caused by: java.lang.NullPointerException"}}
日志在下方显示相同的异常
21:18:46,697 INFO [org.keycloak.subsystem.server.extension.KeycloakProviderDeploymentProcessor] (MSC service thread 1-1) Deploying Keycloak provider: token-enhancer-1.0-SNAPSHOT.jar
21:18:46,718 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-1) MSC000001: Failed to start service jboss.deployment.unit."token-enhancer-1.0-SNAPSHOT.jar".POST_MODULE: org.jboss.msc.service.StartException in service jboss.deployment.unit."token-enhancer-1.0-SNAPSHOT.jar".POST_MODULE: WFLYSRV0153: Failed to process phase POST_MODULE of deployment "token-enhancer-1.0-SNAPSHOT.jar"
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:183)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1738)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.execute(ServiceControllerImpl.java:1700)
at org.jboss.msc.service.ServiceControllerImpl$ControllerTask.run(ServiceControllerImpl.java:1558)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
at org.keycloak.services.DefaultKeycloakSessionFactory.isInternal(DefaultKeycloakSessionFactory.java:370)
at org.keycloak.services.DefaultKeycloakSessionFactory.loadFactories(DefaultKeycloakSessionFactory.java:219)
at org.keycloak.services.DefaultKeycloakSessionFactory.deploy(DefaultKeycloakSessionFactory.java:115)
at org.keycloak.provider.ProviderManagerRegistry.deploy(ProviderManagerRegistry.java:42)
at org.keycloak.subsystem.server.extension.KeycloakProviderDeploymentProcessor.deploy(KeycloakProviderDeploymentProcessor.java:55)
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:176)
... 8 more
21:18:46,719 ERROR [org.jboss.as.controller.management-operation] (DeploymentScanner-threads - 1) WFLYCTL0013: Operation ("full-replace-deployment") failed - address: ([]) - failure description: {"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"token-enhancer-1.0-SNAPSHOT.jar\".POST_MODULE" => "WFLYSRV0153: Failed to process phase POST_MODULE of deployment \"token-enhancer-1.0-SNAPSHOT.jar\"
Caused by: java.lang.NullPointerException"}}
我已将示例代码上传到github。
我实现的ProtocolMapper类如下。
我度过了一段艰难的时光,因为我不知道在哪里使用此类模糊的错误消息进行故障排除。调查这个问题的最佳策略是什么?
import org.keycloak.models.ClientSessionContext;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.protocol.oidc.mappers.*;
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.IDToken;
import java.util.*;
public class KeycloakTokenEnhancer extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper {
public static final String PROVIDER_ID = "oidc-token-enhancer-mapper";
private static final List<ProviderConfigProperty> configProperties = new ArrayList<>();
static {
OIDCAttributeMapperHelper.addIncludeInTokensConfig(configProperties, KeycloakTokenEnhancer.class);
}
@Override
public AccessToken transformAccessToken(AccessToken accessToken, ProtocolMapperModel protocolMapperModel, KeycloakSession keycloakSession, UserSessionModel userSessionModel, ClientSessionContext clientSessionContext) {
return accessToken;
}
@Override
public String getDisplayCategory() {
return "Token Enhancer mapper";
}
@Override
public String getDisplayType() {
return "Token Enhancer Mapper";
}
@Override
public String getHelpText() {
return "Add to claims for the User Service";
}
@Override
public List<ProviderConfigProperty> getConfigProperties() {
return configProperties;
}
@Override
public String getId() {
return PROVIDER_ID;
}
protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession) {
token.getOtherClaims().put("fruit", "pear, apple, tangerine");
}
public static ProtocolMapperModel create(String name, boolean accessToken, boolean idToken, boolean userInfo) {
ProtocolMapperModel mapper = new ProtocolMapperModel();
mapper.setName(name);
mapper.setProtocolMapper(PROVIDER_ID);
mapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
Map<String, String> config = new HashMap<String, String>();
if (accessToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true");
if (idToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true");
if (userInfo) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_USERINFO, "true");
mapper.setConfig(config);
return mapper;
}
}
答案 0 :(得分:1)
尝试在班级(package
)的顶部添加一个KeycloakTokenEnhancer
语句,然后将班级移到包中。
从line 370 in DefaultKeycloakSessionFactory抛出NPE:
String packageName = factory.getClass().getPackage().getName();
另请参阅: Javadoc of Class.html#getPackage
返回:
类的程序包;如果归档或代码库中没有可用的程序包信息,则为null。