GET OS-OAUTH2/authorize should allow be invoked without x-auth-token ?
Is there any way to invoke /v3/OS-OAUTH2/authorize without provide a x-auth-token in the request? I'm expecting that a third app could invoke keystone by GET
GET <keystone>/v3/OS-OAUTH2/authorize?client_id=${CONSUMER_ID}&redirect_uri=https%3A%2F%2my_app%2Fauthorize&response_type=code&scope=AAA&state=XXX"
but request_authorization_code https://github.com/ging/keystone-oauth2-extension/blob/master/oauth2/controllers.py#L153 is controlled.protected (requires a token) and stores credentials with an user id.
Short answer: No, an X-Auth-Token is needed. The request to GET /OS-OAUTH2/authorize is done by the request owner user-agent after being redirected by the client (not by the client itself). The current implementation requires that the Resource Owner is already authenticated when the flow starts.
I know this is a limitation and I have a solution designed for it. Sadly, I don't know when I will be able to implement it. Do you need it or are you asking just to understand how it works? I can prioritize it if there is a specific need.
Long answer (or why does it work like this):
This is very tricky and has to do with the fact that OAuth2.0 is made (but not restricted to) with web-browsers in mind. The user-agent in the Keystone use case won't be a web browser and there are no nice HTML web forms...
Currently, the endpoint GET /OS-OAUTH2/authorize corresponds to steps A and part of step B in the Authorization Code Grant flow while POST /OS-OAUTH2/authorize implements the other part of B and step C.
The steps are detailed here. In sum:
- Step A is the Authorization Request, with all the required parameters like client_id, redirect_uri, etc. It is initiated by the client (consumer/app/etc.) by redirect the resource owner user-agent.
- Step B is about authenticating the resource owner and establishing if access is granted or not. I think the RFC makes a poor job explaining this step, as it might be one request (the POST) or multiple (if the user needs to authenticate first).
- Step C is the Authorization Response, where the access code is issued and the resource owner is redirected.
In an ideal world (i.e. a web page and a web browser), after Step A the credentials are stored in the Authorization server in a cookie or other session mechanism. Once the user authenticates (if needed) and grants authorization to the client (Step B) those credentials are retrieved from the 'session', and the rest of the authorization code flow happens. Because HTTP is stateless, this 'session' idea has to be implemented through cookies or other mechanisms, which are not available to Keystone (as far as I know). Therefore, the credentials (authorization request params) have to be stored with the user ID in order to be able to identify them when the user makes the POST to authorize. To be able to do this, we require the user to be authenticated (Step B part 1) hence the need of the X-Auth-Token.
If you look at an example (for example this one in Django) they use this session idea. When they need to authenticate the user (not showed in the example), they can add the credentials to the body payload and extract them after the authentication with another redirect to GET /authorize.
The solution for this should be Keystone not storing the credentials and just returning them if they are valid (a response to Step A). The user-agent must then add this credentials when performing the POST /OS-OAUTH2/authorize , for example in the request body. the user-agent should handle the storing of this credentials if user authentication must be done during Step B.
This is a complicated and confusing issue. I wrote this long answer as a reference for the future too, but let me know if you don't agree with something. I'll keep the issue open until a decision is done on when and how to implement the fix.
Well, in fact we are trying to deploy a custom channel for IFTTT with authentication based on oauth2: https://developers.ifttt.com/docs/api_reference#authentication-flow And this implies to perform a GET like that without x-auth-token It would be nice to have it
I'll take a look into it then. Just in case, remember that you need to redirect the resource owner to Keystone and authenticate it anyway, so you will need the x-auth-token later (in the POST /authorize).
Sure, I will need later an x-auth-token to POST /authorize. A GET like that is needed in others auth providers:
- Wordpress: https://developer.wordpress.com/docs/oauth2/
- Reddit: http://hackathon.ttcloud.net:8008/iota/services
- https://developer.github.com/v3/oauth/#redirect-users-to-request-github-access
I was looking for OAuth2 implementation in Keystone and stumbled on the custom extension you've built. I understand from your comment that "Resource owner is already authenticated before start of the flow..." and you also mentioned that you've a flow that you've thought about. Can you please draft your thoughts as to what you've thought about?
@karunchennuri hi, I just read your comment now, so sorry for the last reply. I left the organization (ging) where I developed the OAuth2 Keystone extension by the end of february so I haven't been following this projects too close.
Are you still interested in the extension? I can give you any information, thoughts, future plans or whatever that you need, I'm happy to help.
btw I think @federicofdez is maintaining this code now, he probably can help you too
Hello @karunchennuri,
Just like @garcianavalon stated a few months ago, the current implementation does require an X-Auth-Token header, i.e. the resource owner must be authenticated beforehand.
An approach to this issue has to do with the user-agent adding the credentials when making the POST /OS-OAUTH2/authorize request. This way, Keystone would not have to store them and the X-Auth-Token header wouldn't be so necessary. Quoting @garcianavalon again:
The solution for this should be Keystone not storing the credentials and just returning them if they are valid (a response to Step A). The user-agent must then add this credentials when performing the POST /OS-OAUTH2/authorize , for example in the request body. the user-agent should handle the storing of this credentials if user authentication must be done during Step B.
However, I'm afraid to say that we are currently not supporting this extension, and it's rather unlikely that we do so within a short-term period. We might resume it in the future but, in the meantime, we'd be happy to merge a pull request from you.
Thank you for writing and sorry for the long delay in writing you a reply.
Regards, Federico
P.S. Thank you too for your reply, @garcianavalon.
Thanks @federicofdez for your reply and Thanks @garcianavalon I kind of made changes to this extension to support Keystone-Liberty. But this still has strong dependency with ADMIN_TOKEN. Do you've any notes on how you've implemented or enhanced this extension esp steps A, B in your previous experience?
@federicofdez I can get back when the extension is ready for you to initiate pull request.