Announcement Announcement Module
Collapse
No announcement yet.
trouble configuring implicit flow Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • trouble configuring implicit flow

    I've implemented a rudimentary resource server, auth server, and client inspired by the sparklr/tonr examples, but with separate auth server and resource server implementations. I'm trying to implement the implicit grant flow using version 1.0.0.RC2.

    When my sample client attempts to access the protected resource using OAuth2RestTemplate, I get the following error:

    Code:
    error="access_denied", error_description="Error requesting access token."
    	at org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport.retrieveToken(OAuth2AccessTokenSupport.java:100)
    	at org.springframework.security.oauth2.client.token.grant.implicit.ImplicitAccessTokenProvider.obtainAccessToken(ImplicitAccessTokenProvider.java:61)
    	at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainNewAccessTokenInternal(AccessTokenProviderChain.java:142)
    	at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainAccessToken(AccessTokenProviderChain.java:118)
    	at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:196)
    	at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:148)
    	at org.springframework.security.oauth2.client.OAuth2RestTemplate.createRequest(OAuth2RestTemplate.java:89)
    	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:434)
    	at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:122)
    	at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:415)
    	at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:213)
    Instead, I was expecting the protected resource to redirect the RestTemplate request to /oauth/authorize.

    My client security config for the authorization code flow was:

    Code:
    <oauth:resource id="rs" type="authorization_code" client-id="client1" client-secret="${password}" access-token-uri="${accessTokenUri}" user-authorization-uri="${userAuthorizationUri}" scope="read" />
    For implicit flow, I've created another client:

    Code:
    <oauth:resource id="rs" type="implicit" client-id="client2" client-secret="${password}" access-token-uri="${accessTokenUri}" user-authorization-uri="${userAuthorizationUri}" scope="read" />
    What am I doing wrong?

  • #2
    I think your assumption about the source of the redirect is wrong. A Resource Server *could* send a redirect to the authorize endpoint I guess, but in general it doesn't have enough information to do so - at a minimum it would need client_id and response_type (and some other stuff in the general case) which is all information available to the client. The Resource Server will probably send a 401 (or maybe 403), and it's up to the client to kow what to do. That's the approach that Spring Security OAuth takes with OAuthRestTemplate (which actually only throws an exception) and the OAuth2ClientContextFilter. But that's not super relevant to the implicit flow (although it is supported, if you can authenticate the call to /authorize) because implicit flows are normally done from the browser, not from a webapp client. So the bottom line is you need to rely on your client library, or handle it yourself.

    Appendix: when I read your post again it is clear that your client *is* OAuth2RestTemplate, presumably in a webapp. That's a strange use of implicit flow, but like I said, not completely outrageous. It looks like you did get redirected to the authorization server and couldn't get a token. You should look at the logs in your auth server to see why (probably the call to /authorize was not authenticated?).
    Last edited by Dave Syer; Aug 31st, 2012, 10:57 AM.

    Comment


    • #3
      Originally posted by Dave Syer View Post
      I think your assumption about the source of the redirect is wrong. A Resource Server *could* send a redirect to the authorize endpoint I guess, but in general it doesn't have enough information to do so - at a minimum it would need client_id and response_type (and some other stuff in the general case) which is all information available to the client...
      Got it. On reviewing my implementation of the authentication code flow, I see that indeed it is the OAuth2RestTemplate which suggests the redirect to the user agent upon receiving a 401 from the resource server.

      Originally posted by Dave Syer View Post
      Appendix: when I read your post again it is clear that your client *is* OAuth2RestTemplate, presumably in a webapp. That's a strange use of implicit flow, but like I said, not completely outrageous. It looks like you did get redirected to the authorization server and couldn't get a token. You should look at the logs in your auth server to see why (probably the call to /authorize was not authenticated?).
      I am aware of the non-standard implementation of the implicit grant flow, but I figured it'd be easier to implement after a copy and edit of my auth code implementation.

      Looking at my auth server logs, I see the following:

      Code:
      Request received for '/oauth/token':
      
      POST /as/oauth/token HTTP/1.1
      Authorization: Basic Y2xpZW50MjpiYXNlYmFsbDI=
      Accept: application/json, application/x-www-form-urlencoded
      Content-Type: application/x-www-form-urlencoded
      User-Agent: Java/1.6.0_33
      Host: localhost:8080
      Connection: keep-alive
      Content-Length: 116
      This is odd, since I expected a GET request to /oauth/authorize (/oauth/token is never used in implicit mode, right?). This leads me to suspect the problem is with this config:

      Code:
      <oauth:resource id="rs" type="implicit" client-id="client2" client-secret="${password}" access-token-uri="${accessTokenUri}" user-authorization-uri="${userAuthorizationUri}" scope="read" />
      Since access-token-uri is required as an attribute, perhaps I could change it to the following:

      Code:
      <oauth:resource id="rs" type="implicit" client-id="client2" client-secret="${password}" access-token-uri="${userAuthorizationUri}" scope="read" />
      Note the omission of the user-authorization-uri attribute (as it is unecessary) and the replacement of the value of the access-token-uri (as tokens are issued by /oauth/authorize in implicit flow). Does this make sense?
      Last edited by jrod; Aug 31st, 2012, 05:05 PM.

      Comment


      • #4
        Yes, that makes sense. I suppose you could argue that in the implicit grant you are obtaining a token from /authorize, so that *is* the token URI, and that must be the reasoning behind the use of that attribute. But I would prefer to change it so it's less confusing, so if you want to raise a JIRA and/or propose a change, please go ahead.

        How are you going to authenticate the request to the /authorize endpoint?

        BTW: you shouldn't need a client secret for an implicit grant, so if it is mandatory we need to fix that as well.

        Comment


        • #5
          Originally posted by Dave Syer View Post
          Yes, that makes sense. I suppose you could argue that in the implicit grant you are obtaining a token from /authorize, so that *is* the token URI, and that must be the reasoning behind the use of that attribute. But I would prefer to change it so it's less confusing, so if you want to raise a JIRA and/or propose a change, please go ahead.
          Yes, that is my reasoning. I've created SECOAUTH-331 to track this issue.

          Originally posted by Dave Syer View Post
          How are you going to authenticate the request to the /authorize endpoint?
          Similar to how sparklr does it, i.e., form-based auth, per the implicit flow example in tonr2/demo.html

          Originally posted by Dave Syer View Post
          BTW: you shouldn't need a client secret for an implicit grant, so if it is mandatory we need to fix that as well.
          Good catch. It was a remnant of my copy and paste from my auth code impl. I removed the secret and it appears to work fine.

          Comment


          • #6
            Originally posted by jrod View Post
            Similar to how sparklr does it, i.e., form-based auth, per the implicit flow example in tonr2/demo.html
            That's not going to work out of the box with the Java client - you will be redirected for authentication, but the cookie you need to send in the authorization request won't be known to the RestTemplate. The tonr2 implicit demo is a JavaScript client and has full use of the browser and its cookie store.

            I guess you might need to ask some questions about what you are really trying to do and if implicit grants from Java clients is the way to go.

            Comment


            • #7
              Originally posted by Dave Syer View Post
              That's not going to work out of the box with the Java client - you will be redirected for authentication, but the cookie you need to send in the authorization request won't be known to the RestTemplate. The tonr2 implicit demo is a JavaScript client and has full use of the browser and its cookie store.
              My apologies in advance, but I'm not sure why this would be the case. Going back slightly, if I understand the spec correctly, the auth code and implicit flows are nearly identical up to the point when the authorization request is made (except for response_type, of course) and both redirect to its respective response URL. On top of that, the Java client approach works for the auth code flow, handling the cookies and redirection (as do sparklr/tonr), so why wouldn't/shouldn't this work for the implicit flow?

              Comment


              • #8
                Originally posted by jrod View Post
                On top of that, the Java client approach works for the auth code flow, handling the cookies and redirection (as do sparklr/tonr), so why wouldn't/shouldn't this work for the implicit flow?
                The auth code flow is different because the client obtains the token using basic authentication on the /token endpoint. In an implicit flow the client contacts the /authorize endpoint directly and the authentication is not defined by the spec. It works for the JavaScript client because it is *in* the browser. Your Java client is sitting in a JVM somewhere with no explicit access to the session cookie the user has with the auth server. That's not to say that you can't make an implicit grant work, just that you will have to arrange for the authentication using some custom code or configuration.

                Comment

                Working...
                X