英文:
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 !
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论