Spring OAuth2 ClientId 作为密码授权类型的用户名传入

Spring OAuth2 ClientId passed in as username for password grant type

我正在尝试 Spring OAuth2 库的一个非常基本的实现;但是,当我向服务器发送请求时,我收到以下错误:

{
"error": "invalid_client",
"error_description": "Bad client credentials"
}

在进行进一步调试时,我注意到出于某种原因,clientId 在资源所有者流中作为用户名传入。

我已经包含了我的 XML 配置,我很想知道是否有人可以告诉我是否有任何内在错误或者是否有人有任何建议。

<bean id="tokenStore"
    class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" />

<bean id="tokenServices"
    class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
    <property name="tokenStore" ref="tokenStore" />
    <property name="supportRefreshToken" value="true" />
    <property name="clientDetailsService" ref="clientDetailsService" />
</bean>

<bean id="oauthAccessDeniedHandler"
    class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />

<bean id="clientCredentialsTokenEndpointFilter"
    class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
    <property name="authenticationManager" ref="authenticationManager" />
</bean>

<bean id="clientAuthenticationEntryPoint"
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <property name="realmName" value="test/client" />
    <property name="typeName" value="Basic" />
</bean>

<security:http pattern="/oauth/token" create-session="stateless"
    authentication-manager-ref="authenticationManager">
    <security:intercept-url pattern="/oauth/token" access="isAuthenticated()" />
    <security:anonymous enabled="false" />
    <security:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
    <!-- include this only if you need to authenticate clients via request 
        parameters -->
    <security:custom-filter ref="clientCredentialsTokenEndpointFilter"
        after="BASIC_AUTH_FILTER" />
    <security:access-denied-handler ref="oauthAccessDeniedHandler" />
    <security:csrf disabled="true"/>
</security:http>

<authorization-server client-details-service-ref="clientDetailsService"
    xmlns="http://www.springframework.org/schema/security/oauth2" token-services-ref="tokenServices" >
    <authorization-code />
    <implicit />
    <refresh-token />
    <client-credentials />
    <password authentication-manager-ref="authenticationManager" />
</authorization-server>

<oauth:resource-server id="resourceFilter" token-services-ref="tokenServices" authentication-manager-ref="authenticationManager" />

<security:authentication-manager id="authenticationManager">
    <security:authentication-provider>
        <security:user-service id="userDetailsService">
            <security:user name="user" password="password" authorities="ROLE_USER" />
        </security:user-service>
    </security:authentication-provider>
</security:authentication-manager>

<client-details-service id="clientDetailsService"
    xmlns="http://www.springframework.org/schema/security/oauth2">
    <oauth:client client-id="my-trusted-client"
        authorized-grant-types="password,authorization_code,refresh_token,implicit"
        scope="read,write,trust" resource-ids="oauth2-resource"
        access-token-validity="60" authorities="ROLE_CLIENT,ROLE_TRUSTED_CLIENT"
        redirect-uri="http://anywhere" />
    <oauth:client client-id="my-client-with-registered-redirect"
        authorized-grant-types="authorization_code" scope="read,trust"
        resource-ids="oauth2-resource" authorities="ROLE_CLIENT"
        redirect-uri="http://anywhere?key=value" />
    <oauth:client client-id="my-client-with-secret" secret="secret"
        authorized-grant-types="password,client_credentials" scope="read"
        resource-ids="oauth2-resource" access-token-validity="60"
        authorities="ROLE_CLIENT" />
</client-details-service>

下面也是我发送给服务器的请求,它被编码为'x-www-form-urlencoded'

grant_type:password
client_id:my-client-with-secret
client_secret:secret
username:user
password:password
scope:read write

问题出在这里:

<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
    <property name="authenticationManager" ref="authenticationManager" />
</bean>

我正在通过用户身份验证管理器而不是客户端详细信息身份验证管理器。必须创建一个类型为 ClientDetailsAuthenticationManager 的附加 bean 并将其传递到 ref.