我有一个具有OAuth2安全性的Spring应用程序。
我可以通过以下请求轻松获得OAuth Bearer 令牌:
POST {{...}}/oauth/token
?grant_type=password
&client_id={{client_id}}
&username={{username}}
&password={{password}}
这将返回一个200 OK
请求,并在响应中带有我的access_token
。
我的问题是,我的一个客户不喜欢在查询中发送纯文本密码作为查询参数的想法,他们希望使用Basic Autentication获得OAuth Bearer令牌。
但是我不能通过以下方式工作:
POST {{...}}/oauth/token
授权: Basic base64encoded(username:password)
内容类型: application/x-www-form-urlencoded
请求正文:
{
"grant_type": "password",
"client_id": {{client_id}}
}
它返回401 Unauthorized
,并且
{
"error": "unauthorized",
"error_description": "Bad credentials"
}
我的applicationContext.xml
文件如下:
<beans>
...
<!-- Definition of the Authentication Service -->
<security:http
pattern="/oauth/token"
create-session="stateless"
authentication-manager-ref="clientAuthenticationManager">
<security:anonymous enabled="false"/>
<security:http-basic entry-point-ref="clientAuthenticationEntryPoint"/>
<security:custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER"/>
<security:access-denied-handler ref="oauthAccessDeniedHandler"/>
</security:http>
<!-- Protected resources -->
<security:http
pattern="/v3/**"
create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager">
<security:anonymous enabled="false"/>
<security:intercept-url pattern="/v3/**" access="IS_AUTHENTICATED_FULLY"/>
<security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/>
<security:access-denied-handler ref="oauthAccessDeniedHandler"/>
</security:http>
<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="typeName" value="Basic"/>
</bean>
<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"/>
<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="clientAuthenticationManager"/>
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased">
<constructor-arg>
<list>
<bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter"/>
<bean class="org.springframework.security.access.vote.RoleVoter"/>
<bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
</list>
</constructor-arg>
</bean>
<security:authentication-manager id="clientAuthenticationManager">
<security:authentication-provider user-service-ref="clientDetailsUserService"/>
</security:authentication-manager>
<bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails"/>
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="myAuthProvider"/>
</security:authentication-manager>
<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="accessTokenValiditySeconds" value="86400"/>
<property name="tokenStore" ref="tokenStore"/>
<property name="supportRefreshToken" value="true"/>
<property name="clientDetailsService" ref="clientDetails"/>
</bean>
<bean id="oAuth2RequestFactory" class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
<constructor-arg ref="clientDetails"/>
</bean>
<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices">
<oauth:authorization-code/>
<oauth:implicit/>
<oauth:refresh-token/>
<oauth:password/>
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter" token-services-ref="tokenServices"/>
<oauth:client-details-service id="clientDetails">
<oauth:client client-id="web-console"
authorized-grant-types="password,authorization_code,refresh_token,implicit,redirect"
authorities="ROLE_CLIENT, ROLE_TRUSTED_CLIENT"
scope="read,write,trust"
access-token-validity="86400"
refresh-token-validity="86400"/>
</oauth:client-details-service>
...
</beans>
理想情况下,我应该可以使用/oauth/token
标头调用Authorization Basic xxxxxxxxxxxxxxx
端点,并且可以获取OAuth承载令牌。