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 OAUTH2 Console when you register your app. Identifies the client that is making the request. The value passed in this parameter must exactly match the value shown in the OpenStackID OAUTH2 Console.
redirect_uri One of the redirect_uri values registered at the OpenStackID OAUTH2 Console. Determines where the response is sent. The value of this parameter must exactly match one of the values registered in the OpenStackID OAUTH2 Console (including https scheme, case, and trailing ‘/’).
scope Space-delimited set of permissions that the application requests. Identifies the OpenStackID API access that your application is requesting. The values 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)

GET api/v1/users/me

Gets additional information about the current user

Example request:

GET /api/v1/users/me HTTP/1.1
Host: openstackid.org
Accept: application/json, text/javascript

Example response:

{

    "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
}