英文:
keycloak : Unrecognized field "access_token"
问题
我有一个关于Keycloak管理客户端的问题。
当我尝试执行以下操作时:
// 创建Keycloak客户端
Keycloak keycloak = KeycloakBuilder.builder()
.serverUrl(keycloakUrlAuth)
.realm(keycloakRealm)
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.clientId(keycloakClientId)
.clientSecret(keycloakClientSecret)
.build();
// 获取访问令牌
AccessTokenResponse token = keycloak.tokenManager().getAccessToken();
return token.getToken();
我总是收到以下错误:
在 [来源: (org.jboss.resteasy.client.jaxrs.internal.ClientResponse$InputStreamWrapper); 行: 1, 列: 18] (通过引用链: org.keycloak.representations.AccessTokenResponse["access_token"]): javax.ws.rs.client.ResponseProcessingException: javax.ws.rs.ProcessingException: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: 未识别的字段 "access_token" (类 org.keycloak.representations.AccessTokenResponse),未标记为可忽略的字段 (已知属性: "tokenType", "notBeforePolicy", "otherClaims", "token", "sessionState", "refreshExpiresIn", "scope", "expiresIn", "refreshToken", "idToken"])
docker-jboss-1 | 在 [来源: (org.jboss.resteasy.client.jaxrs.internal.ClientResponse$InputStreamWrapper); 行: 1, 列: 18] (通过引用链: org.keycloak.representations.AccessTokenResponse["access_token"])
docker-jboss-1 | 在 org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:138)
docker-jboss-1 | 在 org.jboss.resteasy.client.jaxrs.internal.proxy.extractors.BodyEntityExtractor.extractEntity(BodyEntityExtractor.java:60)
docker-jboss-1 | 在 org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:104)
docker-jboss-1 | 在 org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:76)
docker-jboss-1 | 在 com.sun.proxy.$Proxy519.grantToken(Unknown Source)
docker-jboss-1 | 在 org.keycloak.admin.client.token.TokenManager.grantToken(TokenManager.java:99)
docker-jboss-1 | 在 org.keycloak.admin.client.token.TokenManager.getAccessToken(TokenManager.java:75)
以下是我的pom.xml:
<properties>
<jackson-version>2.13.3</jackson-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!-- 其他依赖,包括Keycloak和Jackson相关的依赖 -->
以及我们使用的jboss-deployment-structure(我们排除了一些模块以使用新版本的Jackson - 需要用于OpenAPI):
<jboss-deployment-structure>
<deployment>
<dependencies>
<system export="true">
<paths>
<path name="sun/reflect"/>
</paths>
</system>
</dependencies>
<exclusions>
<module name="org.dom4j"/>
<module name="com.fasterxml.jackson.core.jackson-core"/>
<module name="com.fasterxml.jackson.core.jackson-annotations"/>
<module name="com.fasterxml.jackson.core.jackson-databind"/>
<module name="com.fasterxml.jackson.datatype.jackson-datatype-jdk8"/>
<module name="com.fasterxml.jackson.datatype.jackson-datatype-jsr310"/>
<module name="com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider"/>
<module name="org.jboss.resteasy.resteasy-jackson2-provider"/>
<module name="org.jboss.resteasy.resteasy-jackson-provider"/>
</exclusions>
</deployment>
</jboss-deployment-structure>
我已经尝试了很多方法,更改版本,排除依赖项,但都不起作用:(
有人能帮助我吗?
谢谢!
英文:
I've a problem with the keycloak admin client.
When I try to do :
// Création d'un client Keycloak
Keycloak keycloak = KeycloakBuilder.builder()
.serverUrl(keycloakUrlAuth)
.realm(keycloakRealm)
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.clientId(keycloakClientId)
.clientSecret(keycloakClientSecret)
.build();
// Obtention du token d'accès
AccessTokenResponse token = keycloak.tokenManager().getAccessToken();
return token.getToken();
I always get this error :
at [Source: (org.jboss.resteasy.client.jaxrs.internal.ClientResponse$InputStreamWrapper); line: 1, column: 18] (through reference chain: org.keycloak.representations.AccessTokenResponse["access_token"]): javax.ws.rs.client.ResponseProcessingException: javax.ws.rs.ProcessingException: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "access_token" (class org.keycloak.representations.AccessTokenResponse), not marked as ignorable (10 known properties: "tokenType", "notBeforePolicy", "otherClaims", "token", "sessionState", "refreshExpiresIn", "scope", "expiresIn", "refreshToken", "idToken"])
docker-jboss-1 | at [Source: (org.jboss.resteasy.client.jaxrs.internal.ClientResponse$InputStreamWrapper); line: 1, column: 18] (through reference chain: org.keycloak.representations.AccessTokenResponse["access_token"])
docker-jboss-1 | at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:138)
docker-jboss-1 | at org.jboss.resteasy.client.jaxrs.internal.proxy.extractors.BodyEntityExtractor.extractEntity(BodyEntityExtractor.java:60)
docker-jboss-1 | at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:104)
docker-jboss-1 | at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:76)
docker-jboss-1 | at com.sun.proxy.$Proxy519.grantToken(Unknown Source)
docker-jboss-1 | at org.keycloak.admin.client.token.TokenManager.grantToken(TokenManager.java:99)
docker-jboss-1 | at org.keycloak.admin.client.token.TokenManager.getAccessToken(TokenManager.java:75)
Here is my pom.xml :
<properties>
<jackson-version>2.13.3</jackson-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.0.26.Final-redhat-1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-cdi</artifactId>
<version>3.0.26.Final-redhat-1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-multipart-provider</artifactId>
<version>3.0.26.Final-redhat-1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-cache-core</artifactId>
<version>3.1.4.Final</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-base</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
<version>3.0.26.Final-redhat-1</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>20.0.5</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-core</artifactId>
<version>20.0.5</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-admin-client</artifactId>
<version>20.0.5</version>
</dependency>
And the jboss-deployment-structure we use (we exclude some modules to be able to use a newer version of jackson - need for openapi) :
<jboss-deployment-structure>
<deployment>
<dependencies>
<system export="true">
<paths>
<path name="sun/reflect"/>
</paths>
</system>
</dependencies>
<exclusions>
<module name="org.dom4j"/>
<module name="com.fasterxml.jackson.core.jackson-core"/>
<module name="com.fasterxml.jackson.core.jackson-annotations"/>
<module name="com.fasterxml.jackson.core.jackson-databind"/>
<module name="com.fasterxml.jackson.datatype.jackson-datatype-jdk8"/>
<module name="com.fasterxml.jackson.datatype.jackson-datatype-jsr310"/>
<module name="com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider"/>
<module name="org.jboss.resteasy.resteasy-jackson2-provider"/>
<module name="org.jboss.resteasy.resteasy-jackson-provider"/>
</exclusions>
</deployment>
</jboss-deployment-structure>
I've tried a lot of things.. Changing the versions, exclude dependencies.. but nothing works
Could someone help me ?
Thank you
答案1
得分: 0
好的,以下是您要的翻译部分:
首先,我终于找到了一些有效的方法(但仍然不明白为什么它不像这样工作).. 这是我目前的解决方案:
首先,我扩展了NamingBase
,以便能够重写字段的名称:
public class CustomNaming extends PropertyNamingStrategies.NamingBase {
public CustomNaming() {
super();
}
@Override
public String translate(String s) {
switch (s) {
case "token":
return "access_token";
case "expiresIn":
return "expires_in";
case "refreshExpiresIn":
return "refresh_expires_in";
case "refreshToken":
return "refreshToken";
case "tokenType":
return "token_type";
case "idToken":
return "id_token";
case "notBeforePolicy":
return "not-before-policy";
case "sessionState":
return "session_state";
case "errorDescription":
return "error_description";
case "errorUri":
return "error_uri";
default:
return s;
}
}
}
然后,我还扩展了ResteasyJackson2Provider
,以使用自定义的命名策略和对象映射器的其他属性:
public class CustomRestEasyJackson2Provider extends ResteasyJackson2Provider {
public CustomRestEasyJackson2Provider() {
super();
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.setPropertyNamingStrategy(new CustomNaming());
setMapper(mapper);
}
}
最后,我在KeycloakBuilder
中使用它:
Keycloak keycloak = KeycloakBuilder.builder()
.serverUrl(keycloakUrlAuth)
.realm(keycloakRealm)
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.clientId(keycloakClientId)
.clientSecret(keycloakClientSecret)
.resteasyClient(new ResteasyClientBuilder()
.register(new CustomRestEasyJackson2Provider(), 1000)
.build())
.build();
这样,它就能够正常工作!
英文:
Well, I finally found something that works (but still don't understand why it doesn't work like that).. Here is my solution for now :
First, I've extended de NamingBase to be able to override de names of the fields :
public class CustomNaming extends PropertyNamingStrategies.NamingBase {
public CustomNaming() {
super();
}
@Override
public String translate(String s) {
switch (s) {
case "token":
return "access_token";
case "expiresIn":
return "expires_in";
case "refreshExpiresIn":
return "refresh_expires_in";
case "refreshToken":
return "refreshToken";
case "tokenType":
return "token_type";
case "idToken":
return "id_token";
case "notBeforePolicy":
return "not-before-policy";
case "sessionState":
return "session_state";
case "errorDescription":
return "error_description";
case "errorUri":
return "error_uri";
default:
return s;
}
}
}
Then, I've also extended de ResteasyJackson2Provider to use that customNaming and other properties in the objectMapper :
public class CustomRestEasyJackson2Provider extends ResteasyJackson2Provider {
public CustomRestEasyJackson2Provider() {
super();
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.setPropertyNamingStrategy(new CustomNaming());
setMapper(mapper);
}
}
And finally, I use it in the KeycloakBuilder :
Keycloak keycloak = KeycloakBuilder.builder()
.serverUrl(keycloakUrlAuth)
.realm(keycloakRealm)
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.clientId(keycloakClientId)
.clientSecret(keycloakClientSecret)
.resteasyClient(new ResteasyClientBuilder()
.register(new CustomRestEasyJackson2Provider(), 1000)
.build())
.build();
Like that, it works !
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论