使用基本身份验证获取OAuth令牌

时间:2018-08-03 15:12:09

标签: spring spring-security oauth oauth-2.0 basic-authentication

背景

我有一个具有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承载令牌。

0 个答案:

没有答案