Announcement Announcement Module
Collapse
No announcement yet.
Resource Owner Password Credentials grant error Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Resource Owner Password Credentials grant error

    Hi,

    I try to use Resource Owner Password Credentials grant type with Spring Security OAuth 2 provider (1.0.0.BUILD-20120718.114859-150).

    My security config looks like
    Code:
        <security:http pattern="/oauth/token" 
                       create-session="stateless" 
                       entry-point-ref="oauth2AuthenticationEntryPoint"
                       authentication-manager-ref="webClientAuthenticationManager">
            <security:anonymous enabled="false" />
            <security:http-basic />
            <security:access-denied-handler ref="oauth2AccessDeniedHandler" />
        </security:http>
    
            <oauth2:authorization-server client-details-service-ref="commonClientDetailsService" 
                                     token-services-ref="tokenServices"
                                     user-approval-handler-ref="userApprovalHandler"
                                     token-endpoint-url="/oauth/token"
                                     authorization-endpoint-url="/oauth/authorize">
                    <oauth2:authorization-code />
    		<oauth2:implicit />
    		<oauth2:refresh-token />
    		<oauth2:client-credentials />
    		<oauth2:password />
        </oauth2:authorization-server>
    When I'm trying to get access_token with following Groovy code
    Code:
    def resourceOwnerAuth = Base64.byteArrayToBase64("$login:$password".getBytes("UTF-8"))
    
    println "Get access token for user $login"
    http.request(POST, JSON) {req ->
            uri.path = "/api/v0.1/oauth/token"
            uri.query = [grant_type: "password"]
            headers.'Authorization' = "Basic $resourceOwnerAuth"
            headers.'Content-Type' = "application/x-www-form-urlencoded;charset=UTF-8"
            
            response.success = { resp, json ->
                assert resp.statusLine.statusCode == 200
                println "access_token: ${json.access_token}"
                println "token_type: ${json.token_type}"
            }
    }
    ResourceOwnerPasswordTokenGranter.getResourceOwner PasswordTokenGranter method throws exception and client gets 500 http status code.

    I've noticed that username and passwoed are nulls after execution
    Code:
    Map<String, String> parameters = clientToken.getAuthorizationParameters();
    String username = parameters.get("username");
    String password = parameters.get("password");
    in ResourceOwnerPasswordTokenGranter.getResourceOwner PasswordTokenGranter and as result inapropriate UsernamePasswordAuthenticationToken is passed to AuthenticationManager.

    Is Spring Security OAuth 2 supporting Resource Owner Password Credentials grant type?
    If so, does it need some tricky configuration?

    Thank you,
    Vitaly Kotlyarenko

  • #2
    You haven't shown your full configuration so I can't see your aithentication managers. A Resource Owner grant obviously requires an AuthenticationManager. The default is to use the standard <security:authentication-manager/>, but if that is absent or you are using a customized one you need to inject it into the <password/> element in the <authorization-server/>.

    Comment


    • #3
      Hi Dave,

      thank you for the response,
      AuthenticationManager was configured with
      Code:
      <security:authentication-manager alias="authenticationManager">
           <security:authentication-provider ref="customCommonAuthProvider"/>
       </security:authentication-manager>
      I fixed the problem by passing username and password in the query string of token request.
      I wonder why this differs from Client Credentials grant type where clientId and secret is not required to be a part of query string?

      Thank you!

      Comment


      • #4
        Originally posted by hipsterJoe View Post
        I wonder why this differs from Client Credentials grant type where clientId and secret is not required to be a part of query string?
        The client is also required to authenticate, and it is preferrable to use the Authorization header for that. You can use query strings optionally according to the spec, but you have to enable it explicitly in Spring Security OAuth2.

        Comment


        • #5
          Hi, I think I'm fundamentally misunderstanding either something about Resource Owner Password Credentials or how Spring Security OAuth implements it.

          From reading the spec, my understanding was that the point of Resource Owner Password Credentials was that the resource owner password was all that was needed to get a token. There is no client credentials mentioned in the diagram. Also in the "Access Token Request" section, it says "the authorization server must... authenticate the client if client authentication is included", which to me implies that client authentication does not need to be included.

          But in TokenEndpoint.getAccessToken(), it throws an exception if there is no principal, and it calls loadClientByClientId() on Principal.getName(). My thought was that I could just pass in the resource owner's username and password, but then what is loadClientByClientId() supposed to return? Does it basically use the same store as the UserDetailsService and there is one "client" per user?

          The way I'm using OAuth is using the browser as the "client". Our UI is a single page app that is using a REST API to get data from the server. As such, it's not a "confidential client" and wouldn't have its own set of credentials.

          Comment


          • #6
            Even an insecure client has to have a client_id. It's not very common to use password grants with such a client, but
            you should be able to send a basic auth header with an empty password, I think. Did you try that?

            Comment


            • #7
              What I don't understand is, what client_id does the browser send in, and when does it get into the datastore that ClientDetailsService is using to loadClientByClientId()?

              With the other OAuth flows, my understanding is that there is generally some registration step outside of the authentication process. So let's say I'm developing a Facebook game called MyFunGame, I would register MyFunGame with Facebook, which now stores MyFunGame in it's client datastore, and I get some password or token that I would use as my client credentials. When a MyFunGame user wants to publish his high score to his Facebook profile, that's when I would redirect him to Facebook's login page, and in that scenario, the client is the MyFunGame server and the resource owner is the game player, and that all makes sense to me.

              But in the case where I just have a browser app talking to a server, there is no registration step, there's no way I'm going to register each and every browser that wants to launch the UI, and even if I did, I wouldn't know how to identify a browser. Do I just have a single "client" called "browser" and every browser sends in the same client id? Or when a new session is loaded, do I dynamically create a new "client" that represents that session?

              Or am I just completely using the wrong flow? Should I be using the Client Credentials flow, but treating the end user as the "client", so that the ClientDetailsServices is essentially a duplicate of UserDetailsServices?

              Comment


              • #8
                As I said, normally a browser would be using an implicit flow, but for that you still need a client registration. The client is not the browser, per se, but the application (script) that is running in the browser, so it totally makes sense to have to register it. If you don't like registration you could make a ClientDetailsService that doesn't require it, but that would be unconventional, and open to abuse (e.g. registering a redirect_uri gives you a level of protection against token theft).

                Comment

                Working...
                X