From a46dd6cb88065976c5015eee6a5a57fe80d84339 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Mon, 14 Jan 2019 03:46:01 +0000 Subject: Refactor the API OAuth docs --- doc/api/oauth2.md | 202 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 124 insertions(+), 78 deletions(-) diff --git a/doc/api/oauth2.md b/doc/api/oauth2.md index 6786c0c5b5c..6e156a14b25 100644 --- a/doc/api/oauth2.md +++ b/doc/api/oauth2.md @@ -1,126 +1,165 @@ # GitLab as an OAuth2 provider -This document covers using the [OAuth2](https://oauth.net/2/) protocol to allow other services access GitLab resources on user's behalf. +This document covers using the [OAuth2](https://oauth.net/2/) protocol to allow +other services to access GitLab resources on user's behalf. -If you want GitLab to be an OAuth authentication service provider to sign into other services please see the [OAuth2 provider](../integration/oauth_provider.md) -documentation. +If you want GitLab to be an OAuth authentication service provider to sign into +other services, see the [OAuth2 provider](../integration/oauth_provider.md) +documentation. This functionality is based on the +[doorkeeper Ruby gem](https://github.com/doorkeeper-gem/doorkeeper). -This functionality is based on [doorkeeper gem](https://github.com/doorkeeper-gem/doorkeeper). +## Supported OAuth2 flows -## Supported OAuth2 Flows +GitLab currently supports the following authorization flows: -GitLab currently supports following authorization flows: +- **Web application flow:** Most secure and common type of flow, designed for + applications with secure server-side. +- **Implicit grant flow:** This flow is designed for user-agent only apps (e.g., single + page web application running on GitLab Pages). +- **Resource owner password credentials flow:** To be used **only** for securely + hosted, first-party services. -- *Web Application Flow* - Most secure and common type of flow, designed for the applications with secure server-side. -- *Implicit Flow* - This flow is designed for user-agent only apps (e.g. single page web application running on GitLab Pages). -- *Resource Owner Password Credentials Flow* - To be used **only** for securely hosted, first-party services. +Refer to the [OAuth RFC](https://tools.ietf.org/html/rfc6749) to find out +how all those flows work and pick the right one for your use case. -Please refer to [OAuth RFC](https://tools.ietf.org/html/rfc6749) to find out in details how all those flows work and pick the right one for your use case. +Both **web application** and **implicit grant** flows require `application` to be +registered first via the `/profile/applications` page in your user's account. +During registration, by enabling proper scopes, you can limit the range of +resources which the `application` can access. Upon creation, you'll obtain the +`application` credentials: _Application ID_ and _Client Secret_ - **keep them secure**. -Both *web application* and *implicit* flows require `application` to be registered first via `/profile/applications` page -in your user's account. During registration, by enabling proper scopes you can limit the range of resources which the `application` can access. Upon creation -you'll obtain `application` credentials: _Application ID_ and _Client Secret_ - **keep them secure**. +CAUTION: **Important:** +OAuth specification advises sending the `state` parameter with each request to +`/oauth/authorize`. We highly recommended sending a unique value with each request +and validate it against the one in the redirect request. This is important in +order to prevent [CSRF attacks](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)). +The `state` parameter really should have been a requirement in the standard! ->**Important:** OAuth specification advises sending `state` parameter with each request to `/oauth/authorize`. We highly recommended to send a unique -value with each request and validate it against the one in redirect request. This is important to prevent [CSRF attacks]. The `state` param really should -have been a requirement in the standard! +In the following sections you will find detailed instructions on how to obtain +authorization with each flow. -In the following sections you will find detailed instructions on how to obtain authorization with each flow. +### Web application flow -### Web Application Flow +NOTE: **Note:** +Check the [RFC spec](https://tools.ietf.org/html/rfc6749#section-4.1) for a +detailed flow description. -Check [RFC spec](http://tools.ietf.org/html/rfc6749#section-4.1) for a detailed flow description +The web application flow is: -#### 1. Requesting authorization code +1. Request authorization code. To do that, you should redirect the user to the + `/oauth/authorize` endpoint with the following GET parameters: -To request the authorization code, you should redirect the user to the `/oauth/authorize` endpoint with following GET parameters: + ``` + https://gitlab.example.com/oauth/authorize?client_id=APP_ID&redirect_uri=REDIRECT_URI&response_type=code&state=YOUR_UNIQUE_STATE_HASH + ``` -``` -https://gitlab.example.com/oauth/authorize?client_id=APP_ID&redirect_uri=REDIRECT_URI&response_type=code&state=YOUR_UNIQUE_STATE_HASH -``` + This will ask the user to approve the applications access to their account and + then redirect back to the `REDIRECT_URI` you provided. The redirect will + include the GET `code` parameter, for example: -This will ask the user to approve the applications access to their account and then redirect back to the `REDIRECT_URI` you provided. The redirect will -include the GET `code` parameter, for example: + ``` + http://myapp.com/oauth/redirect?code=1234567890&state=YOUR_UNIQUE_STATE_HASH + ``` -`http://myapp.com/oauth/redirect?code=1234567890&state=YOUR_UNIQUE_STATE_HASH` + You should then use `code` to request an access token. -You should then use the `code` to request an access token. +1. Once you have the authorization code you can request an `access_token` using the + code. You can do that by using any HTTP client. In the following example, + we are using Ruby's `rest-client`: -#### 2. Requesting access token + ```ruby + parameters = 'client_id=APP_ID&client_secret=APP_SECRET&code=RETURNED_CODE&grant_type=authorization_code&redirect_uri=REDIRECT_URI' + RestClient.post 'http://gitlab.example.com/oauth/token', parameters + ``` -Once you have the authorization code you can request an `access_token` using the code, to do that you can use any HTTP client. In the following example, -we are using Ruby's `rest-client`: + Example response: -``` -parameters = 'client_id=APP_ID&client_secret=APP_SECRET&code=RETURNED_CODE&grant_type=authorization_code&redirect_uri=REDIRECT_URI' -RestClient.post 'http://gitlab.example.com/oauth/token', parameters + ```json + { + "access_token": "de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54", + "token_type": "bearer", + "expires_in": 7200, + "refresh_token": "8257e65c97202ed1726cf9571600918f3bffb2544b26e00a61df9897668c33a1" + } + ``` -# The response will be -{ - "access_token": "de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54", - "token_type": "bearer", - "expires_in": 7200, - "refresh_token": "8257e65c97202ed1726cf9571600918f3bffb2544b26e00a61df9897668c33a1" -} -``` ->**Note:** -The `redirect_uri` must match the `redirect_uri` used in the original authorization request. +NOTE: **Note:** +The `redirect_uri` must match the `redirect_uri` used in the original +authorization request. You can now make requests to the API with the access token returned. +### Implicit grant flow -### Implicit Grant - -Check [RFC spec](http://tools.ietf.org/html/rfc6749#section-4.2) for a detailed flow description. - -Unlike the web flow, the client receives an `access token` immediately as a result of the authorization request. The flow does not use client secret -or authorization code because all of the application code and storage is easily accessible, therefore __secrets__ can leak easily. +NOTE: **Note:** +Check the [RFC spec](https://tools.ietf.org/html/rfc6749#section-4.2) for a +detailed flow description. ->**Important:** Avoid using this flow for applications that store data outside of the GitLab instance. If you do, make sure to verify `application id` -associated with access token before granting access to the data +CAUTION: **Important:** +Avoid using this flow for applications that store data outside of the GitLab +instance. If you do, make sure to verify `application id` associated with the +access token before granting access to the data (see [/oauth/token/info](https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples#get----oauthtokeninfo)). +Unlike the web flow, the client receives an `access token` immediately as a +result of the authorization request. The flow does not use the client secret +or the authorization code because all of the application code and storage is +easily accessible, therefore secrets can leak easily. -#### 1. Requesting access token - -To request the access token, you should redirect the user to the `/oauth/authorize` endpoint using `token` response type: +To request the access token, you should redirect the user to the +`/oauth/authorize` endpoint using `token` response type: ``` https://gitlab.example.com/oauth/authorize?client_id=APP_ID&redirect_uri=REDIRECT_URI&response_type=token&state=YOUR_UNIQUE_STATE_HASH ``` -This will ask the user to approve the application's access to their account and then redirect back to the `REDIRECT_URI` you provided. The redirect -will include a fragment with `access_token` as well as token details in GET parameters, for example: +This will ask the user to approve the application's access to their account and +then redirect them back to the `REDIRECT_URI` you provided. The redirect +will include a fragment with `access_token` as well as token details in GET +parameters, for example: ``` http://myapp.com/oauth/redirect#access_token=ABCDExyz123&state=YOUR_UNIQUE_STATE_HASH&token_type=bearer&expires_in=3600 ``` -### Resource Owner Password Credentials +### Resource owner password credentials flow -Check [RFC spec](http://tools.ietf.org/html/rfc6749#section-4.3) for a detailed flow description. +NOTE: **Note:** +Check the [RFC spec](https://tools.ietf.org/html/rfc6749#section-4.3) for a +detailed flow description. -> **Deprecation notice:** Starting in GitLab 8.11, the Resource Owner Password Credentials has been *disabled* for users with two-factor authentication -turned on. These users can access the API using [personal access tokens] instead. +NOTE: **Note:** +The Resource Owner Password Credentials is disabled for users with [two-factor +authentication](../user/profile/account/two_factor_authentication.md) turned on. +These users can access the API using [personal access tokens](../user/profile/personal_access_tokens.md) +instead. -In this flow, a token is requested in exchange for the resource owner credentials (username and password). -The credentials should only be used when there is a high degree of trust between the resource owner and the client (e.g. the -client is part of the device operating system or a highly privileged application), and when other authorization grant types are not -available (such as an authorization code). +In this flow, a token is requested in exchange for the resource owner credentials +(username and password). ->**Important:** -Never store the user's credentials and only use this grant type when your client is deployed to a trusted environment, in 99% of cases [personal access tokens] -are a better choice. +The credentials should only be used when: -Even though this grant type requires direct client access to the resource owner credentials, the resource owner credentials are used -for a single request and are exchanged for an access token. This grant type can eliminate the need for the client to store the -resource owner credentials for future use, by exchanging the credentials with a long-lived access token or refresh token. +- There is a high degree of trust between the resource owner and the client. For + example, the client is part of the device operating system or a highly + privileged application. +- Other authorization grant types are not available (such as an authorization code). -#### 1. Requesting access token +CAUTION: **Important:** +Never store the user's credentials and only use this grant type when your client +is deployed to a trusted environment, in 99% of cases +[personal access tokens](../user/profile/personal_access_tokens.md) are a better +choice. -POST request to `/oauth/token` with parameters: +Even though this grant type requires direct client access to the resource owner +credentials, the resource owner credentials are used for a single request and +are exchanged for an access token. This grant type can eliminate the need for +the client to store the resource owner credentials for future use, by exchanging +the credentials with a long-lived access token or refresh token. -``` +To request an access token, you must make a POST request to `/oauth/token` with +the following parameters: + +```json { "grant_type" : "password", "username" : "user@example.com", @@ -128,6 +167,13 @@ POST request to `/oauth/token` with parameters: } ``` +Example cURL request: + +```sh +echo 'grant_type=password&username=&password=' > auth.txt +curl --data "@auth.txt" --request POST https://gitlab.example.com/oauth/token +``` + Then, you'll receive the access token back in the response: ``` @@ -138,7 +184,7 @@ Then, you'll receive the access token back in the response: } ``` -For testing you can use the oauth2 ruby gem: +For testing, you can use the `oauth2` Ruby gem: ``` client = OAuth2::Client.new('the_client_id', 'the_client_secret', :site => "http://example.com") @@ -148,7 +194,9 @@ puts access_token.token ## Access GitLab API with `access token` -The `access token` allows you to make requests to the API on a behalf of a user. You can pass the token either as GET parameter +The `access token` allows you to make requests to the API on behalf of a user. +You can pass the token either as GET parameter: + ``` GET https://gitlab.example.com/api/v4/user?access_token=OAUTH-TOKEN ``` @@ -159,5 +207,3 @@ or you can put the token to the Authorization header: curl --header "Authorization: Bearer OAUTH-TOKEN" https://gitlab.example.com/api/v4/user ``` -[personal access tokens]: ../user/profile/personal_access_tokens.md -[CSRF attacks]: http://www.oauthsecurity.com/#user-content-authorization-code-flow -- cgit v1.2.1