oauth2.md 7.77 KB
Newer Older
1
# GitLab as an OAuth2 provider
2

3 4
This document covers using the [OAuth2](https://oauth.net/2/) protocol to allow
other services to access GitLab resources on user's behalf.
5

6 7 8 9
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).
10

11
## Supported OAuth2 flows
12

13
GitLab currently supports the following authorization flows:
14

15 16 17 18 19 20
- **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.
21

22 23
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.
24

25 26 27 28 29
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**.
30

31 32 33 34 35 36
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!
37

38 39
In the following sections you will find detailed instructions on how to obtain
authorization with each flow.
40

41
### Web application flow
42

43 44 45
NOTE: **Note:**
Check the [RFC spec](https://tools.ietf.org/html/rfc6749#section-4.1) for a
detailed flow description.
46

47
The web application flow is:
48

49 50
1. Request authorization code. To do that, you should redirect the user to the
   `/oauth/authorize` endpoint with the following GET parameters:
51

52 53 54
   ```
   https://gitlab.example.com/oauth/authorize?client_id=APP_ID&redirect_uri=REDIRECT_URI&response_type=code&state=YOUR_UNIQUE_STATE_HASH
   ```
55

56 57 58
   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:
59

60 61 62
   ```
   http://myapp.com/oauth/redirect?code=1234567890&state=YOUR_UNIQUE_STATE_HASH
   ```
63

64
   You should then use `code` to request an access token.
65

66 67 68
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`:
69

70 71 72 73
   ```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
   ```
74

75
   Example response:
76

77 78 79 80 81 82 83 84
   ```json
   {
    "access_token": "de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54",
    "token_type": "bearer",
    "expires_in": 7200,
    "refresh_token": "8257e65c97202ed1726cf9571600918f3bffb2544b26e00a61df9897668c33a1"
   }
   ```
85

86 87 88
NOTE: **Note:**
The `redirect_uri` must match the `redirect_uri` used in the original
authorization request.
89 90 91

You can now make requests to the API with the access token returned.

92
### Implicit grant flow
93

94 95 96
NOTE: **Note:**
Check the [RFC spec](https://tools.ietf.org/html/rfc6749#section-4.2) for a
detailed flow description.
97

98 99 100 101
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
102
(see [/oauth/token/info](https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples#get----oauthtokeninfo)).
103

104 105 106 107
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.
108

109 110
To request the access token, you should redirect the user to the
`/oauth/authorize` endpoint using `token` response type:
111 112

```
113
https://gitlab.example.com/oauth/authorize?client_id=APP_ID&redirect_uri=REDIRECT_URI&response_type=token&state=YOUR_UNIQUE_STATE_HASH
114 115
```

116 117 118 119
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:
120 121

```
122
http://myapp.com/oauth/redirect#access_token=ABCDExyz123&state=YOUR_UNIQUE_STATE_HASH&token_type=bearer&expires_in=3600
123 124
```

125
### Resource owner password credentials flow
126

127 128 129
NOTE: **Note:**
Check the [RFC spec](https://tools.ietf.org/html/rfc6749#section-4.3) for a
detailed flow description.
130

131 132 133 134 135
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.
136

137 138
In this flow, a token is requested in exchange for the resource owner credentials
(username and password).
139

140
The credentials should only be used when:
141

142 143 144 145
- 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).
146

147 148 149 150 151
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.
152

153 154 155 156 157
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.
158

159 160 161 162
To request an access token, you must make a POST request to `/oauth/token` with
the following parameters:

```json
163 164 165
{
  "grant_type"    : "password",
  "username"      : "user@example.com",
166
  "password"      : "secret"
167 168 169
}
```

170 171 172 173 174 175 176
Example cURL request:

```sh
echo 'grant_type=password&username=<your_username>&password=<your_password>' > auth.txt
curl --data "@auth.txt" --request POST https://gitlab.example.com/oauth/token
```

177 178 179 180 181 182 183 184 185 186
Then, you'll receive the access token back in the response:

```
{
  "access_token": "1f0af717251950dbd4d73154fdf0a474a5c5119adad999683f5b450c460726aa",
  "token_type": "bearer",
  "expires_in": 7200
}
```

187
For testing, you can use the `oauth2` Ruby gem:
188 189 190

```
client = OAuth2::Client.new('the_client_id', 'the_client_secret', :site => "http://example.com")
191
access_token = client.password.get_token('user@example.com', 'secret')
192
puts access_token.token
193
```
194

195
##  Access GitLab API with `access token`
196

197 198 199
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:

200 201 202 203 204 205 206 207 208 209
```
GET https://gitlab.example.com/api/v4/user?access_token=OAUTH-TOKEN
```

or you can put the token to the Authorization header:

```
curl --header "Authorization: Bearer OAUTH-TOKEN" https://gitlab.example.com/api/v4/user
```