================== OAuth 2.0 endpoint ================== Using OAuth 2.0 to Access OpenStackID APIs ------------------------------------------ OpenStackID APIs use the OAuth 2.0 protocol for authorization. OpenStackID supports common OAuth 2.0 scenarios such as those for web server, Service Accounts, and client-side applications. OAuth 2.0 is a relatively simple protocol. To begin, you register your application with OpenStackID. Then your client application requests an access token from the OpenStackID Authorization Server, extracts a token from the response, and sends the token to the OpenStackID API that you want to access. Basic steps ----------- All applications follow a basic pattern when accessing an OpenStackID API using OAuth 2.0. At a high level, you follow four steps: 1. Register your application. All applications that access an OpenStackID API must be registered through the OpenStackID OAUTH2 Console. The result of this registration process is a set of values (such as a client ID and client secret) that are known to both OpenStackID and your application. The set of values varies based on what type of application you are building. For example, a JavaScript application does not require a secret, but a web server application does. 2. Obtain an access token from the OpenStackID Authorization Server. Before your application can access private data using an OpenStackID API, it must obtain an access token that grants access to that API. A single access token can grant varying degrees of access to multiple APIs. A variable parameter called "scope" controls the set of resources and operations that an access token permits. During the access-token request, your application sends one or more values in the scope parameter. Some requests require an authentication step where the user logs in with their OpenStackID account. After logging in, the user is asked whether they are willing to grant the permissions that your application is requesting. This process is called user consent. If the user grants the permission, the OpenStackID Authorization Server sends your application an access token (or an authorization code that your application can use to obtain an access token). If the user does not grant the permission, the server returns an error. 3.Send the access token to an API. After an application obtains an access token, it sends the token to an OpenStackID API in an HTTP authorization header. It is possible to send tokens as URI query-string parameters, but we don't recommend it, because URI parameters can end up in log files that are not completely secure. Access tokens are valid only for the set of operations and resources described in the scope of the token request. 4.Refresh the access token (if necessary) Access tokens have limited lifetimes. If your application needs access to an OpenStackID API beyond the lifetime of a single access token, it can obtain a refresh token. A refresh token allows your application to obtain new access tokens. Scenarios ========= Web server applications ----------------------- The OpenStackID OAuth 2.0 endpoint supports web server applications that use languages and frameworks such as PHP, Java, Python, Ruby, and ASP.NET. These applications might access an OpenStackID API while the user is present at the application or after the user has left the application. **This flow requires that the application can keep a secret.** Overview -------- The authorization sequence begins when your application redirects a browser to the OpenStackID OAuth 2.0 Endpoint; the URL includes query parameters that indicate the type of access being requested.The result is an authorization code, which OpenStackID returns to your application in a query string. After receiving the authorization code, your application can exchange the code (along with a client ID and client secret) for an access token and, in some cases, a refresh token. The application can then use the access token to access an OpenStackID API. If a refresh token is present in the authorization code exchange, then it can be used to obtain new access tokens at any time. This is called **offline access**, because the user does not have to be present at the browser when the application obtains a new access token. Forming the URL --------------- The URL used when authenticating a user is https://openstackid.org/oauth2/auth. This endpoint is accessible over SSL, and HTTP connections are refused. This endpoint is the target of the initial request. It handles active session lookup, authenticating the user, and user consent. The result of requests to this endpoint include access tokens, refresh tokens, and authorization codes. The set of query string parameters supported by the OpenStackID Authorization Server for web server applications are: +------------------------------+---------------------------------------------------+---------------------------------------------------------------------------------------+ | Parameter | Values | Description | +==============================+===================================================+=======================================================================================+ | response_type | code | Determines whether the OpenStackID OAuth 2.0 endpoint returns an authorization code. | | | | Web server applications should use code. | | | | | +------------------------------+---------------------------------------------------+---------------------------------------------------------------------------------------+ | client_id | The client ID you obtain from the OpenStackID | Identifies the client that is making the request. The value passed in this parameter | | | OAUTH2 Console when you register your app. | must exactly match the value shown in | | | | the OpenStackID OAUTH2 Console. | | | | | +------------------------------+---------------------------------------------------+---------------------------------------------------------------------------------------+ | redirect_uri | One of the redirect_uri values registered at the | Determines where the response is sent. The value of this parameter must exactly match | | | OpenStackID OAUTH2 Console. | one of the values registered in the OpenStackID OAUTH2 Console | | | | (including https scheme, case, and trailing '/'). | | | | | +------------------------------+---------------------------------------------------+---------------------------------------------------------------------------------------+ | scope | Space-delimited set of permissions that the | Identifies the OpenStackID API access that your application is requesting. The values | | | application requests. | passed in this parameter inform the consent screen that is shown to the user. | | | | | +------------------------------+---------------------------------------------------+---------------------------------------------------------------------------------------+ | state | Any string | Provides any state that might be useful to your application upon receipt of the | | | | response. The Openstack Authorization Server roundtrips this parameter, so your | | | | application receives the same value it sent. Possible uses include redirecting the | | | | user to the correct resource in your site, nonces, and cross-site-request-forgery | | | | mitigations. | | | | | +------------------------------+---------------------------------------------------+---------------------------------------------------------------------------------------+ | access_type | online or offline | Indicates whether your application needs to access an OpenStackID API when the user | | | | is not present at the browser. This parameter defaults to online. If your application | | | | needs to refresh access tokens when the user is not present at the browser, | | | | then use offline. This will result in your application obtaining a refresh token the | | | | first time your application exchanges an authorization code for a user. | | | | | +------------------------------+---------------------------------------------------+---------------------------------------------------------------------------------------+ | approval_prompt | force or auto | Indicates whether the user should be re-prompted for consent. The default is auto, | | | | so a given user should only see the consent page for a given set of scopes the first | | | | time through the sequence. If the value is force, then the user sees a consent page | | | | even if they previously gave consent to your application for a given set of scopes. | | | | | +------------------------------+---------------------------------------------------+---------------------------------------------------------------------------------------+ Handling the response --------------------- The response will be sent to the redirect_uri as specified in the request URL. If the user approves the access request, then the response contains an authorization code and the state parameter (if included in the request). If the user does not approve the request, the response contains an error message. All responses are returned to the web server on the query string, as shown below: An error response:: https://oauth2-demo.com/code?error=access_denied&state=xyz An authorization code response:: https://oauth2-demo.com/code?state=xyz&code=123456 After the web server receives the authorization code, it may exchange the authorization code for an access token and a refresh token. This request is an HTTPS post, and includes the following parameters: +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | Parameter | Description | +==============================+=================================================================================================================================+ | code | The authorization code returned from the initial request. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | client_id | The client ID obtained from the OpenStackID OAUTH2 Console during application registration. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | client_secret | The client secret obtained during application registration | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | redirect_uri | The URI registered with the application. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | grant_type | As defined in the OAuth 2.0 specification, this field must contain a value of authorization_code. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ **REMARK** It is advisable that you exclude client_id/client_secret params from query string and use instead the Authorization Header like this:: Authorization: Basic Base64-Encoded(client_id:client_secret) The actual request might look like the following:: POST /oauth2/token HTTP/1.1 Host: OpenStackID.openstack.org Authorization: Basic Base64-Encoded(client_id:client_secret) Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb A successful response to this request contains the following fields: +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | Field | Description | +==============================+=================================================================================================================================+ | access_token | The token that can be sent to an OpenStackID API. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | refresh_token | A token that may be used to obtain a new access token. Refresh tokens are valid until the user revokes access. | | | This field is only present if access_type=offline is included in the authorization code request. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | expires_in | The remaining lifetime of the access token in seconds. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | token_type | Identifies the type of token returned. At this time, this field will always have the value Bearer. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ An example successful response:: HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"Bearer", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", } Calling an OpenStackID API -------------------------- After your application obtains an access token, you can use the token to make calls to a OpenStackID API on behalf of a given user. To do this, include the access token in a request to the API by including either an access_token query parameter or an Authorization: Bearer HTTP header. When possible, it is preferable to use the HTTP Header, since query strings tend to be visible in server logs. Examples Here is a call to the same API for the authenticated user (me) using the access_token Authorization Bearer HTTP header:: GET /api/v1/users/me HTTP/1.1 Authorization: Bearer 1/fFBGRNJru1FQd44AzqT3Zg Host: OpenStackID.openstack.org Offline access -------------- In some cases, your application may need to access an OpenStackID API when the user is not present. This style of access is called offline, and web server applications may request offline access from a user. The normal and default style of access is called online. If your application needs offline access to an OpenStackID API, then the request for an authorization code should include the access_type parameter, where the value of that parameter is offline. The first time a given user's browser is sent to this URL, they see a consent page. If they grant access, then the response includes an authorization code which may be redeemed for an access token and a refresh token. If this is the first time the application has exchanged an authorization code for a user, then the response includes an access token and a refresh token, as shown below:: { "access_token":"1/fFAGRNJru1FTz70BzhT3Zg", "expires_in":3600, "token_type":"Bearer", "refresh_token":"1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" } **IMPORTANT**: When your application receives a refresh token, it is important to store that refresh token for future use. If your application loses the refresh token, it will have to re-prompt the user for consent before obtaining another refresh token. If you need to re-prompt the user for consent, include the approval_prompt parameter in the authorization code request, and set the value to force. After your application receives the refresh token, it may obtain new access tokens at any time. The next time your application requests an authorization code for that user, the user will not be asked to grant consent (assuming they previously granted access, and you are asking for the same scopes). As expected, the response includes an authorization code which may be redeemed. However, unlike the first time an authorization code is exchanged for a given user, a refresh token will not be returned from the authorization code exchange. The following is an example of such a response:: { "access_token":"1/fFAGRNJru1FQd77BzhT3Zg", "expires_in":3600, "token_type":"Bearer" } Using a refresh token --------------------- As indicated in the previous section, a refresh token is obtained in offline scenarios during the first authorization code exchange. In these cases, your application may obtain a new access token by sending a refresh token to the OpenStackID OAuth 2.0 Authorization server. To obtain a new access token this way, your application performs an HTTPS POST to https://openstackid.org/oauth2/token. The request must include the following parameters: +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | Parameter | Description | +==============================+=================================================================================================================================+ | refresh_token | (required) The refresh token returned from the authorization code exchange. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | grant_type | (required) As defined in the OAuth 2.0 specification, this field must contain a value of refresh_token. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | scope | (optional) The requested scope MUST NOT include any scope not originally granted by the resource owner, and if omitted is | | | treated as equal to the scope originally granted by the resource owner. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ Such a request will look similar to the following:: POST /oauth2/token HTTP/1.1 Host: OpenStackID.openstack.org Authorization: Basic Base64-Encoded(client_id:client_secret) Content-Type: application/x-www-form-urlencoded grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA As long as the user has not revoked the access granted to your application, the response includes a new access token. A response from such a request is shown below:: { "access_token":"1/fFBGRNJru1FQd44AzqT3Zg", "expires_in":3600, "token_type":"Bearer" } Revoking a token ---------------- In some cases a user may wish to revoke access given to an application. A user can revoke access by visiting the following URL and explicitly revoking access: https://openstackid.org/admin/grants . It is also possible for an application to programmatically revoke the access given to it. Programmatic revocation is important in instances where a user unsubscribes or removes an application. In other words, part of the removal process can include an API request to ensure the permissions granted to the application are removed. To programmatically revoke a token, your application makes a request to https://openstackid.org/oauth2/token/revoke and includes the token as a parameter and a hint +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | Parameter | Description | +==============================+=================================================================================================================================+ | token | (required) Token value to revoke | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | token_type_hint | (optional) access_token/refresh_token Hint to allow Authorization Server to do a more performant token search | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ The token can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked. If the revocation is successfully processed, then the status code of the response is 200. For error conditions, a status code 400 is returned along with an error code. Token Introspection ------------------- In OAuth 2.0, the contents of tokens are opaque to clients. This means that the client does not need to know anything about the content or structure of the token itself, if there is any. However, there is still a large amount of metadata that may be attached to a token, such as its current validity, approved scopes, and extra information about the authentication context in which the token was issued. These pieces of information are often vital to Protected Resources making authorization decisions based on the tokens being presented. Since OAuth2 defines no direct relationship between the Authorization Server and the Protected Resource, only that they must have an agreement on the tokens themselves, there have been many different approaches to bridging this gap. OpenStackID Authorization Server implements `OAuth Token Introspection `_ to fix that gap. To programmatically get info for a token, your application makes a request to https://openstackid.org/oauth2/token/introspection Such a request will look similar to the following:: POST /oauth2/token/introspection HTTP/1.1 Host: OpenStackID.openstack.org Authorization: Basic Base64-Encoded(client_id:client_secret) Content-Type: application/x-www-form-urlencoded token=tGzv3JOkF0XG5Qx2TlKWIA **IMPORTANT** the token must belongs to clientid provided on the request, otherwise request will fail The TokenInfo endpoint will respond with a JSON array that describes the token or an error. Below is a table of the fields included in the non-error case: +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | Parameter | Description | +==============================+=================================================================================================================================+ | audience | The Resource Server that is the intended target of the token. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | access_token | Token Value | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | client_id | The application that is the intended target of the token. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | scope | The space-delimited set of scopes that the user consented to. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | expires_in | The number of seconds left in the lifetime of the token. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | token_type | Identifies the type of token returned. At this time, this field will always have the value Bearer. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | userid | This field is only present if a resource owner (end-user) had approved access on the consent screen. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | application_type | identifies the client type. (WEB_APPLICATION, JS_CLIENT OR SERVICE ) | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | allowed_return_uris | identifies the allowed return uris set for this client. | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | allowed_origins | This field is only present if application_type == JS_CLIENT. | | | identifies the allowed origin uris set for this client. | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ A response from such a request is shown below:: { "access_token":"1/fFBGRNJru1FQd44AzqT3Zg", "client_id": "xyz", "expires_in":3600, "token_type":"Bearer", "scope":"profile email", "audience": "resource.server1.com", "user_id": 123456, "application_type": "WEB_APPLICATION", "allowed_return_uris": "www.test.com", "allowed_origins": "www.test1.com", } Using OAuth 2.0 for Client-side Applications ============================================ The OpenStackID OAuth 2.0 endpoint supports JavaScript-centric applications. These applications may access an OpenStackID API while the user is present at the application, and this type of application cannot keep a secret. Overview -------- This scenario begins by redirecting a browser (full page or popup) to a OpenStackID URL with a set of query parameters that indicate the type of OpenStackID API access the application requires. As in other scenarios, OpenStackID handles user authentication and consent, and the result is an access token. OpenStackID returns the access token on the fragment of the response, and client side script extracts the access token from the response. The application may access an OpenStackID API after it receives the access token. **NOTE:** Your application should always use HTTPS in this scenario. Handling the response --------------------- OpenStackID returns an access token to your application if the user grants your application the permissions it requested. The access token is returned to your application in the fragment as part of the access_token parameter. Since a fragment is not returned to the server, client-side script must parse the fragment and extract the value of the access_token parameter. Other parameters included in the response include expires_in and token_type. These parameters describe the lifetime of the token in seconds, and the kind of token that is being returned. If the state parameter was included in the request, then it is also included in the response. An example User Agent flow response is shown below:: https://oauth2-demo.com//oauthcallback#access_token=123456&token_type=Bearer&expires_in=3600 Calling an OpenStackID API -------------------------- After your application obtains an access token, you can use the token to make calls to an OpenStackID API on behalf of a given user. To do this, include the access token in a request to the API by including either an access_token query parameter or an Authorization: Bearer HTTP header. When possible, it is preferable to use the HTTP Header, since query strings tend to be visible in server logs. **NOTE**: Be sure that OpenStackID Endpoint API that your application wants to access it's been `CORS `_ enabled User API -------- Allows to get additional info about current user (Me) .. http:get:: api/v1/users/me Gets additional information about the current user **Example request**: .. sourcecode:: http GET /api/v1/users/me HTTP/1.1 Host: openstackid.org Accept: application/json, text/javascript **Example response**: .. sourcecode:: http { "name":"Sebastian", "family_name":"Marcet", "nickname":"Sebastian Marcet", "picture":"http:\/\/www.openstack.org\/assets\/profile-images\/IMG-20140912-WA0003.jpg", "birthdate":"", "gender":"Male", "email":"sebastian@tipit.net" } Using OAuth 2.0 for Server to Server Applications ------------------------------------------------- The OpenStackID OAuth 2.0 Authorization Server supports server-to-server interactions. The requesting application has to prove its own identity to gain access to an API, and an end-user doesn't have to be involved. The client can request an access token using only its client credentials (or other supported means of authentication) when the client is requesting access to the protected resources under its control, or those of another resource owner that have been previously arranged with the authorization server. The client makes a request to the token endpoint by adding the following parameters: +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | Parameter | Description | +==============================+=================================================================================================================================+ | grant_type | (required) Value MUST be set to "client_credentials". | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | scope | (required) Required Scopes | | | | +------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ For example, the client makes the following HTTP request using transport-layer security (with extra line breaks for display purposes only):: POST /oauth2/token HTTP/1.1 Host: https://openstackid.org/ Authorization: Basic Base64-Encoded(client_id:client_secret) Content-Type: application/x-www-form-urlencoded grant_type=client_credentials&scope=write.endpoint.api An example successful response:: HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"123456", "token_type":"Bearer", "expires_in":3600 }