2016-07-06 166 views
0

我的服務器中有一個oauth服務,它執行身份驗證操作並在有效用戶發出請求時發出訪問令牌。然後,當我嘗試使用命令行卷曲請求此服務時要求我越來越低於錯誤。當請求oauth2訪問令牌時獲取無效範圍

"detailMessage":"Invalid scope: read,write,trust","cause":{"additionalInformation":{"scope":"read trust write"} 

以下是我的要求,其結果是錯誤。

curl -X POST http://localhost:8080/MyProjectOauth/oauth/token -H 「Accept: application/json」 -d "grant_type=password&client_id=client1&client_secret=client1&username=user1&password=user1&scope=read,write,trust" 

如果我在沒有範圍的情況下嘗試了這個請求,那麼會出現下面的錯誤。

"detailMessage":"Bad credentials","cause":{"detailMessage":"Bad credentials" 

下面是我的spring安全配置文件。

彈簧security.xml文件:

 <?xml version="1.0" encoding="UTF-8" ?> 
    <beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oauth="http://www.springframework.org/schema/security/oauth2" 
    xmlns:sec="http://www.springframework.org/schema/security" xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd 
     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd 
     http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd "> 

     <http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager" 
      xmlns="http://www.springframework.org/schema/security"> 
      <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY"/> 
      <anonymous enabled="false"/> 
      <http-basic entry-point-ref="clientAuthenticationEntryPoint"/> 
      <!-- include this only if you need to authenticate clients via request parameters --> 
      <custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER"/> 
      <access-denied-handler ref="oauthAccessDeniedHandler"/> 
     </http> 

     <!-- The OAuth2 protected resources are separated out into their own block so we can deal with authorization and error handling 
     separately. This isn't mandatory, but it makes it easier to control the behaviour. --> 
     <http pattern="/protected/**" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint" 
      access-decision-manager-ref="accessDecisionManager" xmlns="http://www.springframework.org/schema/security"> 
      <anonymous enabled="false"/> 
      <intercept-url pattern="/protected/**" access="ROLE_USER"/> 
      <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/> 
      <access-denied-handler ref="oauthAccessDeniedHandler"/> 
     </http> 

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

     <bean id="clientAuthenticationEntryPoint" 
      class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> 
      <property name="realmName" value="test/client"/> 
      <property name="typeName" value="Basic"/> 
     </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="clientAuthenticationManager"/> 
     </bean> 

     <bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased" 
      xmlns="http://www.springframework.org/schema/beans"> 
      <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> 

     <authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security"> 
      <authentication-provider user-service-ref="clientDetailsUserService"/> 
     </authentication-manager> 

     <bean id="passwordEncoder" 
      class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"> 
      <constructor-arg name="strength" value="11"/> 
     </bean> 

     <authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security"> 
      <authentication-provider user-service-ref="userService"> 
       <password-encoder ref="passwordEncoder"/> 
      </authentication-provider> 
     </authentication-manager> 

     <bean id="clientDetailsUserService" 
      class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService"> 
      <constructor-arg ref="clientDetails"/> 
     </bean> 

     <!-- Used for the persistenceof tokens (currently an in memory implementation) --> 
     <bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore"> 
    <!--   <constructor-arg ref="dataSource"/> --> 
     </bean> 

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

     <bean id="oAuth2RequestFactory" 
      class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory"> 
      <constructor-arg ref="clientDetails"/> 
     </bean> 

     <bean id="userApprovalHandler" 
      class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler"> 
      <property name="tokenStore" ref="tokenStore"/> 
      <property name="requestFactory" ref="oAuth2RequestFactory"/> 
     </bean> 


     <!-- authorization-server aka AuthorizationServerTokenServices is an interface that defines everything necessary for token management --> 
     <oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices" 
            user-approval-handler-ref="userApprovalHandler"> 
      <oauth:authorization-code/> 
      <oauth:implicit/> 
      <oauth:refresh-token/> 
      <oauth:client-credentials/> 
      <oauth:password/> 
     </oauth:authorization-server> 

     <oauth:resource-server id="resourceServerFilter" resource-id="test" token-services-ref="tokenServices"/> 

     <bean id="clientDetails" 
      class="com.example.myproject.ser.ClientService"> 
     </bean> 

     <sec:global-method-security pre-post-annotations="enabled" proxy-target-class="true"> 
      <!--you could also wire in the expression handler up at the layer of the http filters. See https://jira.springsource.org/browse/SEC-1452 --> 
      <sec:expression-handler ref="oauthExpressionHandler"/> 
     </sec:global-method-security> 

     <oauth:expression-handler id="oauthExpressionHandler"/> 

     <oauth:web-expression-handler id="oauthWebExpressionHandler"/> 

    </beans> 

ClientService.java:

 import org.springframework.beans.factory.annotation.Autowired; 
    import org.springframework.security.oauth2.provider.ClientDetails; 
    import org.springframework.security.oauth2.provider.ClientDetailsService; 
    import org.springframework.security.oauth2.provider.ClientRegistrationException; 
    import org.springframework.security.oauth2.provider.client.BaseClientDetails; 
    import org.springframework.stereotype.Component; 

    import com.example.myproject.rep.OauthRepository; 

    @Component 
    public class ClientService implements ClientDetailsService { 

     @Autowired 
     private OauthRepository oauthRepository; 

     @Override 
     public ClientDetails loadClientByClientId(String s) throws ClientRegistrationException { 
      BaseClientDetails clientDetails = oauthRepository.getByClientId(s); 
      return clientDetails; 
     } 
    } 

OauthRepository.java:

 @Repository 
    @Transactional 
    public class OauthRepository { 

    @Autowired 
    private SessionFactory sessionFactory; 

    private org.hibernate.Session getCurrentSession(){ 
     return sessionFactory.getCurrentSession(); 
    } 



     public BaseClientDetails getByClientId(String clientId) { 
     Query query=getCurrentSession().createQuery("FROM OauthClientDetails WHERE clientId=:clientId"); 
     query.setParameter("clientId", clientId); 
     List<OauthClientDetails> getClient=query.list(); 

     OauthClientDetails oauthClient=getClient.get(0); 
     BaseClientDetails details = new BaseClientDetails(oauthClient.getClientId(),oauthClient.getResourceIds(),oauthClient.getScope(),oauthClient.getAuthorizedGrantTypes(),oauthClient.getAuthorities()); 
     details.setClientSecret(oauthClient.getClientSecret()); 

      return details; 



     } 
     } 

下面是我的數據庫客戶端表中的數據。

  CREATE TABLE oauth_client_details (
     client_id varchar(50) NOT NULL, 
     resource_ids varchar(256) DEFAULT NULL, 
     client_secret varchar(256) DEFAULT NULL, 
     scope varchar(256) DEFAULT NULL, 
     authorized_grant_types varchar(256) DEFAULT NULL, 
     web_server_redirect_uri varchar(256) DEFAULT NULL, 
     authorities varchar(256) DEFAULT NULL, 
     access_token_validity int(11) DEFAULT NULL, 
     refresh_token_validity int(11) DEFAULT NULL, 
     additional_information varchar(4096) DEFAULT NULL, 
     autoapprove varchar(4096) DEFAULT NULL, 
     PRIMARY KEY (client_id) 
    ); 


INSERT INTO oauth_client_details(client_id, resource_ids, client_secret, scope, authorized_grant_types, authorities, access_token_validity, refresh_token_validity) 
VALUES ('client1', 'rest_api', 'client1', 'read,write,trust', 'password,authorization_code,refresh_token,implicit', 'ROLE_ANDROID', '5', '1000'); 

請幫我解決這個問題

+0

根據RFC 6749(https://tools.ietf.org/html/rfc6749#section-3.3) 「scope參數的值表示爲空格分隔的區分大小寫字符串的列表「。 您的請求param看起來是用逗號分隔的: 「&scope =讀取,寫入,信任」 –

+0

@ Jim.R那麼我該寫些什麼呢? – KJEjava48

+0

這應該工作 - curl -X POST http:// localhost:8080/MyProjectOauth/oauth/token -H「Accept:application/json」-d「grant_type = password&client_id = client1&client_secret = client1&username = user1&password = user1&scope = read write trust」 –

回答

0

範圍參數應以空格隔開。

這應該工作 - 捲曲-X POST本地主機:8080/MyProjectOauth /的OAuth /令牌-H「接受:應用/ JSON的」 -d「grant_type =密碼&的client_id =客戶端1 & client_secret =客戶端1 &用戶名= USER1 & pass word = user1 & scope = rea d write trust「

Jim R在上述評論中回答了這個問題。我只是把它移到一個答案,所以它會更容易找到。

相關問題