stormpath-rails 2.2.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.gitmodules +3 -0
- data/.travis.yml +1 -1
- data/CHANGELOG.md +11 -0
- data/README.md +1 -1
- data/app/controllers/stormpath/rails/register/create_controller.rb +1 -1
- data/docs/Makefile +225 -0
- data/docs/_static/facebook-new-project.png +0 -0
- data/docs/_static/facebook-url-settings.png +0 -0
- data/docs/_static/forgot-change.png +0 -0
- data/docs/_static/forgot-complete.png +0 -0
- data/docs/_static/forgot-email-sent.png +0 -0
- data/docs/_static/forgot-email.png +0 -0
- data/docs/_static/forgot-init.png +0 -0
- data/docs/_static/forgot.png +0 -0
- data/docs/_static/github_create_app.png +0 -0
- data/docs/_static/google-enable-login.png +0 -0
- data/docs/_static/google-new-project.png +0 -0
- data/docs/_static/google-oauth-settings.png +0 -0
- data/docs/_static/id-site-login.png +0 -0
- data/docs/_static/id-site-settings.png +0 -0
- data/docs/_static/id-site-stormpath-config.png +0 -0
- data/docs/_static/linkedin-add-authorized-urls.gif +0 -0
- data/docs/_static/linkedin-add-permissions.gif +0 -0
- data/docs/_static/linkedin-new-application.gif +0 -0
- data/docs/_static/linkedin-permissions-page.png +0 -0
- data/docs/_static/login-page-basic.png +0 -0
- data/docs/_static/login-page-facebook-permissions.png +0 -0
- data/docs/_static/login-page-facebook.png +0 -0
- data/docs/_static/login-page-google-account.png +0 -0
- data/docs/_static/login-page-google.png +0 -0
- data/docs/_static/login-page-linkedin.png +0 -0
- data/docs/_static/login-page.png +0 -0
- data/docs/_static/login_page_with_all_providers.png +0 -0
- data/docs/_static/registration-page-basic.png +0 -0
- data/docs/_static/registration-page-error.png +0 -0
- data/docs/_static/registration-page.png +0 -0
- data/docs/_static/verification-complete.png +0 -0
- data/docs/_static/verification-email.png +0 -0
- data/docs/_static/verification.png +0 -0
- data/docs/_templates/layout.html +6 -0
- data/docs/about.rst +72 -0
- data/docs/authentication.rst +332 -0
- data/docs/changelog.rst +41 -0
- data/docs/conf.py +346 -0
- data/docs/configuration.rst +151 -0
- data/docs/contributors.rst +56 -0
- data/docs/devise_import.rst +112 -0
- data/docs/help.rst +24 -0
- data/docs/index.rst +31 -0
- data/docs/login.rst +242 -0
- data/docs/logout.rst +73 -0
- data/docs/password_reset.rst +85 -0
- data/docs/quickstart.rst +179 -0
- data/docs/registration.rst +364 -0
- data/docs/social_login.rst +409 -0
- data/docs/templates.rst +100 -0
- data/docs/user_data.rst +216 -0
- data/lib/stormpath/rails/version.rb +1 -1
- data/stormpath-rails.gemspec +1 -1
- metadata +57 -4
@@ -0,0 +1,332 @@
|
|
1
|
+
.. _authentication:
|
2
|
+
|
3
|
+
Authentication
|
4
|
+
==============
|
5
|
+
|
6
|
+
This library offers several options for securing your application and
|
7
|
+
authenticating your users. Which strategy should you use? The answer depends
|
8
|
+
on your use case, and we'll discuss each one in detail. But at a high level,
|
9
|
+
your choices look like this:
|
10
|
+
|
11
|
+
* If you are building a traditional web app or single page application, you
|
12
|
+
should use **Cookie Authentication**.
|
13
|
+
|
14
|
+
* If you are building a mobile application, you should use the **OAuth2
|
15
|
+
Password Grant**.
|
16
|
+
|
17
|
+
* If you are building an API service, you can use
|
18
|
+
**HTTP Basic Authentication** or **OAuth2 Client Credentials**.
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
Cookie Authentication
|
23
|
+
---------------------
|
24
|
+
|
25
|
+
If you are building a web application that serves traditional HTML pages, or a
|
26
|
+
Single Page Application (Angular/React), this library will handle the cookies
|
27
|
+
for you. No special configuration is necessary.
|
28
|
+
|
29
|
+
To use cookie authentication, simply use the ``require_authentication!`` before action:
|
30
|
+
|
31
|
+
.. code-block:: ruby
|
32
|
+
|
33
|
+
class ProfilesController < ApplicationController
|
34
|
+
before_action :require_authentication!
|
35
|
+
|
36
|
+
def show
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
Behind the scenes we are issuing a OAuth2 Access Token and Refresh Token for
|
41
|
+
the user, and storing them in secure, HTTPS-Only cookies. After the user has
|
42
|
+
logged in, these cookies will be supplied on every request. Our library will
|
43
|
+
assert that the Access Token is valid. If the Access Token is expired, we will
|
44
|
+
attempt to refresh it with the Refresh Token.
|
45
|
+
|
46
|
+
|
47
|
+
.. note::
|
48
|
+
Stormpath-Rails's OAuth2 cookie feature will not interfere with any
|
49
|
+
existing cookie-based session middleware you might have. The cookies that
|
50
|
+
Stormpath creates are used exclusively for Stormpath's purposes, so it's
|
51
|
+
safe to create your own separate sessions if needed.
|
52
|
+
|
53
|
+
.. _setting_token_expiration_time:
|
54
|
+
|
55
|
+
Setting Token Expiration Time
|
56
|
+
.............................
|
57
|
+
|
58
|
+
If you need to change the expiration time of the Access Token or Refresh Token,
|
59
|
+
please login to the Stormpath Admin Console and navigate to the OAuth policy of
|
60
|
+
your Stormpath Application. There you will find the settings for each token.
|
61
|
+
|
62
|
+
.. _configuring_cookie_flags:
|
63
|
+
|
64
|
+
Configuring Cookie Flags
|
65
|
+
........................
|
66
|
+
|
67
|
+
This library creates two cookies, one for the Access Token and one for the
|
68
|
+
Refresh Token. There are several options available for controlling the flags
|
69
|
+
that are set on these cookies.
|
70
|
+
|
71
|
+
Here is an example configuration block, with the default settings:
|
72
|
+
|
73
|
+
.. code-block:: yaml
|
74
|
+
|
75
|
+
web:
|
76
|
+
accessTokenCookie:
|
77
|
+
name: "access_token"
|
78
|
+
httpOnly: true
|
79
|
+
secure: null
|
80
|
+
path: null
|
81
|
+
domain: null
|
82
|
+
|
83
|
+
refreshTokenCookie:
|
84
|
+
name: "refresh_token"
|
85
|
+
httpOnly: true
|
86
|
+
secure: null
|
87
|
+
path: null
|
88
|
+
domain: null
|
89
|
+
|
90
|
+
|
91
|
+
This table describes each setting in detail:
|
92
|
+
|
93
|
+
+-------------+---------+------------------------------------------------------+
|
94
|
+
| Cookie Flag | Default | Description |
|
95
|
+
+=============+=========+======================================================+
|
96
|
+
| domain | null | Set if needed, e.g. "subdomain.mydomain.com". |
|
97
|
+
+-------------+---------+------------------------------------------------------+
|
98
|
+
| httpOnly | true | True by default, do not disable without good reason |
|
99
|
+
| | | (exposes tokens to XSS | attacks). |
|
100
|
+
+-------------+---------+------------------------------------------------------+
|
101
|
+
| path | "/" | Set if needed, e.g. "/newapp". |
|
102
|
+
+-------------+---------+------------------------------------------------------+
|
103
|
+
| secure | null | Will be ``true`` in HTTPS environments (as detected |
|
104
|
+
| | | by ``req.protocol``), unless explicitly set to |
|
105
|
+
| | | ``false`` (not recommended!). |
|
106
|
+
+-------------+---------+------------------------------------------------------+
|
107
|
+
|
108
|
+
.. _token_validation_strategy:
|
109
|
+
|
110
|
+
Token Validation Strategy
|
111
|
+
.........................
|
112
|
+
|
113
|
+
When a request comes to your server, this gem will use the Access Token
|
114
|
+
and Refresh Token cookies to make an authentication decision. The default
|
115
|
+
validation strategy (``local``) works like this:
|
116
|
+
|
117
|
+
- If the Access Token signature is valid, and the token is not expired, accept
|
118
|
+
the request.
|
119
|
+
|
120
|
+
- If the Access Token is expired, attempt to get a new one from the Stormpath
|
121
|
+
REST API by using the Refresh Token.
|
122
|
+
|
123
|
+
- If a new Access Token cannot be obtained, deny the request.
|
124
|
+
|
125
|
+
With the ``local`` option, our gem only checks the signature and expiration of
|
126
|
+
the Access Token. It does not check with the Stormpath REST API to assert that
|
127
|
+
the Access Token hasn't been revoked.
|
128
|
+
|
129
|
+
If you would like to check for Access Token revocation on every request, you
|
130
|
+
should opt-in to the ``stormpath`` validation strategy. This will make a
|
131
|
+
network call to the Stormpath REST API. If the Access Token has been revoked,
|
132
|
+
or the account has been disabled or deleted, the request will be rejected.
|
133
|
+
|
134
|
+
Opt-in to ``stormpath`` validation with this configuration:
|
135
|
+
|
136
|
+
.. code-block:: yaml
|
137
|
+
|
138
|
+
web:
|
139
|
+
oauth2:
|
140
|
+
password:
|
141
|
+
validationStrategy: 'stormpath'
|
142
|
+
|
143
|
+
|
144
|
+
.. warning::
|
145
|
+
|
146
|
+
When using local validation, your server will not be aware of token revocation
|
147
|
+
or any changes to the associated Stormpath account. **This is a security
|
148
|
+
trade-off that optimizes for performance.** If you prefer extra security, use
|
149
|
+
the ``stormpath`` validation option.
|
150
|
+
|
151
|
+
If you prefer local validation, for the performance reasons, you can add more
|
152
|
+
security by doing one of the following:
|
153
|
+
|
154
|
+
* Use a short expiration time for your Access Tokens (such as five minutes or
|
155
|
+
less). This will limit the amount of time that the Access Token can be used
|
156
|
+
for validation, while still reducing the number of times that we need to
|
157
|
+
make a REST API call, with the refresh token, to get a new access token.
|
158
|
+
|
159
|
+
* Maintain a blacklist of revoked Access Tokens, in your local application
|
160
|
+
cache. Implement a middleware function that asserts that the Access Token is
|
161
|
+
not in this cache, and reject the request if true. We may implement this as
|
162
|
+
a convenience feature in the future.
|
163
|
+
|
164
|
+
|
165
|
+
HTTP Basic Authentication
|
166
|
+
-------------------------
|
167
|
+
|
168
|
+
This strategy makes sense if you are building a simple API service that does
|
169
|
+
not have complex needs around authorization and resource control. This strategy
|
170
|
+
is simple because the developer simply supplies their API keys on every request
|
171
|
+
to your server.
|
172
|
+
|
173
|
+
Once the developer has their API keys, they will use them to authenticate with your
|
174
|
+
API. For each request they will set the ``Authorization`` header, like this::
|
175
|
+
|
176
|
+
Authorization: Basic <Base64UrlSafe(apiKeyId:apiKeySecret)>
|
177
|
+
|
178
|
+
How this is done will depend on what tool or library they are using. For example,
|
179
|
+
if using curl:
|
180
|
+
|
181
|
+
.. code-block:: sh
|
182
|
+
|
183
|
+
curl -v --user apiKeyId:apiKeySecret http://localhost:3000/secret
|
184
|
+
|
185
|
+
You only need to set the *require_authentication!* callback, but behind the curtains another class is going to be invoked,
|
186
|
+
which will handle the basic authentication.
|
187
|
+
|
188
|
+
|
189
|
+
OAuth2 Client Credentials
|
190
|
+
-------------------------
|
191
|
+
|
192
|
+
If you are building an API service and you have complex needs around
|
193
|
+
authorization and security, this strategy should be used. In this situation
|
194
|
+
the developer does a one-time exchange of their API Keys for an Access Token.
|
195
|
+
This Access Token is time limited and must be periodically refreshed. This adds a
|
196
|
+
layer of security, at the cost of being more complex than HTTP Basic
|
197
|
+
Authentication.
|
198
|
+
|
199
|
+
If you're not sure which strategy to use, it's best to start with HTTP Basic
|
200
|
+
Authentication. You can always switch to OAuth2 at a later time.
|
201
|
+
|
202
|
+
Once a developer has an API Key pair (see above, *Issuing API Keys*), they will
|
203
|
+
need to use the OAuth2 Token Endpoint to obtain an Access Token. In simple
|
204
|
+
HTTP terms, that request looks like this::
|
205
|
+
|
206
|
+
|
207
|
+
POST /oauth/token HTTP/1.1
|
208
|
+
Host: myapi.com
|
209
|
+
Content-Type: application/x-www-form-urlencoded
|
210
|
+
Authorization: Basic <Base64UrlSafe(apiKeyId:apiKeySecret)>
|
211
|
+
|
212
|
+
grant_type=client_credentials
|
213
|
+
|
214
|
+
How you construct this request will depend on your library or tool, but the key
|
215
|
+
parts you need to know are:
|
216
|
+
|
217
|
+
* The request must be a POST request.
|
218
|
+
* The content type must be form encoded, and the body must contain
|
219
|
+
``grant_type=client_credentials``.
|
220
|
+
* The Authorization header must be Basic and contain the Base64 Url-Encoded
|
221
|
+
values of the Api Key Pair.
|
222
|
+
|
223
|
+
If you were doing this request with curl, it would look like this::
|
224
|
+
|
225
|
+
curl -X POST --user api_key_id:api_key_secret http://localhost:3000/oauth/token -d grant_type=client_credentials
|
226
|
+
|
227
|
+
If the credentials are valid, you will get an Access Token response that looks
|
228
|
+
like this::
|
229
|
+
|
230
|
+
{
|
231
|
+
"access_token": "eyJ0eXAiOiJKV1QiL...",
|
232
|
+
"token_type": "bearer",
|
233
|
+
"expires_in": 3600
|
234
|
+
}
|
235
|
+
|
236
|
+
|
237
|
+
The response is a JSON object which contains:
|
238
|
+
|
239
|
+
- ``access_token`` - Your OAuth Access Token. This can be used to authenticate
|
240
|
+
on future requests.
|
241
|
+
- ``token_type`` - This will always be ``"bearer"``.
|
242
|
+
- ``expires_in`` - This is the amount of seconds (*as an integer*) for which
|
243
|
+
this token is valid.
|
244
|
+
|
245
|
+
With this token you can now make requests to your API. This request is simpler,
|
246
|
+
as only thing you need to supply is ``Authorization`` header with the Access
|
247
|
+
Token as a bearer token. If you are using curl, that request looks like this:
|
248
|
+
|
249
|
+
.. code-block:: sh
|
250
|
+
|
251
|
+
curl -v -H "Authorization: Bearer eyJ0eXAiOiJKV1QiL..." http://localhost:3000/secret
|
252
|
+
|
253
|
+
In order to protect your API endpoint and allow this form of authentication,
|
254
|
+
you just need to use the *require_authentication!* callback again.
|
255
|
+
|
256
|
+
By default the Access Tokens are valid for one hour. If you want to change
|
257
|
+
the expiration of these tokens you will need to configure it in the server
|
258
|
+
configuration, like this:
|
259
|
+
|
260
|
+
.. code-block:: yaml
|
261
|
+
|
262
|
+
web:
|
263
|
+
oauth2:
|
264
|
+
client_credentials:
|
265
|
+
accessToken:
|
266
|
+
ttl: 3600 // your custom TTL, in seconds, goes here
|
267
|
+
|
268
|
+
|
269
|
+
OAuth2 Password Grant
|
270
|
+
---------------------
|
271
|
+
|
272
|
+
This is the authentication strategy that you will want to use for mobile clients.
|
273
|
+
In this situation the end-user supplies their username and password to your
|
274
|
+
mobile application. The mobile application sends that username and password to
|
275
|
+
your Rails application, which then verifies the password with Stormpath.
|
276
|
+
|
277
|
+
If the account is valid and the password is correct, Stormpath will generate
|
278
|
+
an Access Token for the user. Your server gets this Access Token from Stormpath
|
279
|
+
and then sends it back to your mobile application.
|
280
|
+
|
281
|
+
The mobile application then stores the Access Token in a secure location, and
|
282
|
+
uses it for future requests to your API. Every time the mobile application uses
|
283
|
+
this Access Token your server will verify that it's still valid, using Stormpath.
|
284
|
+
|
285
|
+
When a user wants to login to your mobile application, the mobile application
|
286
|
+
should make this request to your Rails application:
|
287
|
+
|
288
|
+
.. code-block:: sh
|
289
|
+
|
290
|
+
POST /oauth/token HTTP/1.1
|
291
|
+
Host: myapi.com
|
292
|
+
Content-Type: application/x-www-form-urlencoded
|
293
|
+
|
294
|
+
grant_type=password
|
295
|
+
&username=user@gmail.com
|
296
|
+
&password=theirPassword
|
297
|
+
|
298
|
+
If the authentication is successful, the Stormpath API will return an Access
|
299
|
+
Token to your mobile application. The response will look like this::
|
300
|
+
|
301
|
+
{
|
302
|
+
"refresh_token": "eyJraWQiOiI2...",
|
303
|
+
"stormpath_access_token_href": "https://api.stormpath.com/v1/accessTokens/3bBAHmSuTJ64DM574awVen",
|
304
|
+
"token_type": "Bearer",
|
305
|
+
"access_token": "eyJraWQiOiI2Nl...",
|
306
|
+
"expires_in": 3600
|
307
|
+
}
|
308
|
+
|
309
|
+
Your mobile application should store the Access Token and Refresh Token. By
|
310
|
+
default the Access Token is valid for 1 hour and the Refresh Token for 60 days.
|
311
|
+
When the Access Token expires you can get a new Access Token by using the
|
312
|
+
Refresh Token, making this request to your Rails application::
|
313
|
+
|
314
|
+
POST /oauth/token HTTP/1.1
|
315
|
+
Host: myapi.com
|
316
|
+
Content-Type: application/x-www-form-urlencoded
|
317
|
+
|
318
|
+
grant_type=refresh_token
|
319
|
+
&refresh_token=eyJraWQiOiI2...
|
320
|
+
|
321
|
+
The response will contain a new Access Token. Once the Refresh Token expires,
|
322
|
+
the user will have to re-authenticate with a username and password.
|
323
|
+
|
324
|
+
You can control the lifetime of the Access Token and Refresh Token by modifying
|
325
|
+
the OAuth Policy of your Stormpath Application. This can be found by logging
|
326
|
+
into the Stormpath Admin Console and finding your Application.
|
327
|
+
|
328
|
+
For full documentation on our OAuth2 Access Token features, please see
|
329
|
+
`Using Stormpath for OAuth 2.0 and Access/Refresh Token Management`_
|
330
|
+
|
331
|
+
.. _Using Stormpath for API Authentication: https://docs.stormpath.com/guides/api-key-management/
|
332
|
+
.. _Using Stormpath for OAuth 2.0 and Access/Refresh Token Management: http://docs.stormpath.com/guides/token-management/
|
data/docs/changelog.rst
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
.. _changelog:
|
2
|
+
|
3
|
+
|
4
|
+
Change Log
|
5
|
+
==========
|
6
|
+
|
7
|
+
Gem changes until version 2.0.1, in descending order.
|
8
|
+
|
9
|
+
Version 2.3.0
|
10
|
+
-------------
|
11
|
+
Released on Nov 08, 2016
|
12
|
+
- Add sphinx documentation
|
13
|
+
- Fix bug when autoLogin and email verification are both enabled
|
14
|
+
|
15
|
+
|
16
|
+
Version 2.2.0
|
17
|
+
-------------
|
18
|
+
Released on Nov 07, 2016
|
19
|
+
|
20
|
+
- Implement Authentication with Social Providers (Facebook, Google, Linkedin, Github)
|
21
|
+
|
22
|
+
Version 2.1.0
|
23
|
+
-------------
|
24
|
+
Released on Nov 02, 2016
|
25
|
+
|
26
|
+
- Create script for generating a rake task responsible for transferring users from devise to Stormpath
|
27
|
+
- Implement ID Site Authentication
|
28
|
+
|
29
|
+
Version 2.0.2
|
30
|
+
-------------
|
31
|
+
Released on Aug 29, 2016
|
32
|
+
|
33
|
+
- Render path links depending on the configuration
|
34
|
+
- Use Faker to generate random test data
|
35
|
+
- Rename all user instances to account
|
36
|
+
|
37
|
+
Version 2.0.1
|
38
|
+
-------------
|
39
|
+
Released on Aug 22, 2016
|
40
|
+
|
41
|
+
- Fix error when showing new_register_path on login page when register is disabled.
|