rails-auth 1.3.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGES.md +30 -0
- data/README.md +27 -485
- data/lib/rails/auth.rb +3 -0
- data/lib/rails/auth/acl.rb +20 -15
- data/lib/rails/auth/acl/matchers/allow_all.rb +1 -1
- data/lib/rails/auth/acl/middleware.rb +6 -1
- data/lib/rails/auth/acl/resource.rb +12 -11
- data/lib/rails/auth/config_builder.rb +83 -0
- data/lib/rails/auth/credentials.rb +17 -32
- data/lib/rails/auth/credentials/injector_middleware.rb +2 -2
- data/lib/rails/auth/env.rb +64 -0
- data/lib/rails/auth/error_page/debug_page.html.erb +2 -2
- data/lib/rails/auth/exceptions.rb +8 -2
- data/lib/rails/auth/helpers.rb +64 -0
- data/lib/rails/auth/monitor/middleware.rb +28 -0
- data/lib/rails/auth/rack.rb +4 -2
- data/lib/rails/auth/rspec/helper_methods.rb +20 -2
- data/lib/rails/auth/version.rb +1 -1
- data/lib/rails/auth/x509/matcher.rb +1 -1
- data/spec/rails/auth/acl/middleware_spec.rb +2 -1
- data/spec/rails/auth/acl/resource_spec.rb +17 -17
- data/spec/rails/auth/acl_spec.rb +3 -3
- data/spec/rails/auth/credentials/injector_middleware_spec.rb +1 -1
- data/spec/rails/auth/credentials_spec.rb +20 -41
- data/spec/rails/auth/env_spec.rb +31 -0
- data/spec/rails/auth/monitor/middleware_spec.rb +39 -0
- data/spec/rails/auth/rspec/helper_methods_spec.rb +26 -0
- data/spec/rails/auth/rspec/matchers/acl_matchers_spec.rb +2 -2
- data/spec/rails/auth/x509/matcher_spec.rb +1 -1
- metadata +8 -3
- data/lib/rails/auth/override.rb +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2322612702ff801d290fd31d9d8502df8b77722d
|
4
|
+
data.tar.gz: 921efc9a87c56702a8f8242644a61614f7a4eef8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5318762dc1c15d4b12bc2f25ec195c5ac3db0251bc83daf22f63687cf5bb5cff3d63d5aa5c44fea978b6ec63e9c4f1bae48e669a7c306d7f8eeb00ad7d9d1962
|
7
|
+
data.tar.gz: 0b5c0890cb347e8e94b6353c9a14d9c5de348eed7417ecbdfc5e73262846e3d57bd778655f462209812ad03d27bec3103f1cebfc2acc36f5e002a458204b63a5
|
data/.rubocop.yml
CHANGED
data/CHANGES.md
CHANGED
@@ -1,3 +1,33 @@
|
|
1
|
+
### 2.0.1 (2016-07-16)
|
2
|
+
|
3
|
+
* [#36](https://github.com/square/rails-auth/pull/36)
|
4
|
+
Extract Rack environment manipulation into the
|
5
|
+
Rails::Auth::Env class.
|
6
|
+
([@tarcieri])
|
7
|
+
|
8
|
+
* [#35](https://github.com/square/rails-auth/pull/35)
|
9
|
+
Make allowed_by a mandatory argument of
|
10
|
+
Rails::Auth.authorized!
|
11
|
+
([@tarcieri])
|
12
|
+
|
13
|
+
### 2.0.0 (2016-07-16; yanked in favor of 2.0.1)
|
14
|
+
|
15
|
+
* [#34](https://github.com/square/rails-auth/pull/34)
|
16
|
+
Rails::Auth.allowed_by stores the matcher used to
|
17
|
+
authorize the request in the Rack environment.
|
18
|
+
([@tarcieri])
|
19
|
+
|
20
|
+
* [#33](https://github.com/square/rails-auth/pull/33)
|
21
|
+
Rails::Auth::Monitor::Middleware provides callbacks
|
22
|
+
for authorization success/failure for logging or
|
23
|
+
monitoring purposes.
|
24
|
+
([@tarcieri])
|
25
|
+
|
26
|
+
* [#32](https://github.com/square/rails-auth/pull/32)
|
27
|
+
Rails::Auth::ConfigBuilder provides a simplified config
|
28
|
+
API for Rails apps.
|
29
|
+
([@tarcieri])
|
30
|
+
|
1
31
|
### 1.3.0 (2016-07-16)
|
2
32
|
|
3
33
|
* [#30](https://github.com/square/rails-auth/pull/30)
|
data/README.md
CHANGED
@@ -6,111 +6,29 @@ Rails::Auth
|
|
6
6
|
[![Coverage Status](https://coveralls.io/repos/github/square/rails-auth/badge.svg?branch=master)](https://coveralls.io/github/square/rails-auth?branch=master)
|
7
7
|
[![Apache 2 licensed](https://img.shields.io/badge/license-Apache2-blue.svg)](https://github.com/square/rails-auth/blob/master/LICENSE)
|
8
8
|
|
9
|
-
Modular resource-based authentication and authorization for Rails/Rack
|
9
|
+
Modular resource-based authentication and authorization for Rails/Rack designed
|
10
|
+
to support [microservice] authentication and [claims-based identity].
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
Rails::Auth is a flexible library designed for both authentication (AuthN) and
|
14
|
-
authorization (AuthZ) using Rack Middleware. It splits the AuthN and AuthZ
|
15
|
-
steps into separate middleware classes, using AuthN middleware to first verify
|
16
|
-
credentials (such as X.509 certificates or cookies), then authorizing the request
|
17
|
-
via separate AuthZ middleware that consumes these credentials, e.g. access
|
18
|
-
control lists (ACLs).
|
19
|
-
|
20
|
-
Rails::Auth can be used to authenticate and authorize end users using browser
|
21
|
-
cookies, service-to-service requests using X.509 client certificates, or any
|
22
|
-
other clients with credentials that have proper authenticating middleware.
|
23
|
-
|
24
|
-
## Architecture
|
25
|
-
|
26
|
-
Rails::Auth makes use of multiple, independent, single-purpose middleware
|
27
|
-
classes to handle specific types of AuthN/AuthZ.
|
28
|
-
|
29
|
-
### AuthN
|
30
|
-
|
31
|
-
Rails::Auth ships with the following AuthN middleware:
|
32
|
-
|
33
|
-
* `Rails::Auth::X509::Middleware`: authenticates X.509 certificates obtained
|
34
|
-
from the Rack environment.
|
35
|
-
|
36
|
-
The goal of Rails::Auth's AuthN middleware is to authenticate *credentials*
|
37
|
-
taken from the Rack environment and place objects representing them under
|
38
|
-
the `"rails-auth.credentials"` key within the Rack environment for use by
|
39
|
-
subsequent AuthN or AuthZ middleware. The built-in support is for X.509
|
40
|
-
client certificates, but other middleware could handle authentication of
|
41
|
-
cookies or (OAuth) bearer credentials.
|
42
|
-
|
43
|
-
The intended usage is to have multiple AuthN middlewares that are capable
|
44
|
-
of extracting different types of credentials, but also allowing AuthZ
|
45
|
-
middleware to apply a single policy to all of them. It's also possible to
|
46
|
-
chain AuthN middleware together such that one credential obtained earlier
|
47
|
-
in the middleware stack is used to authenticate another (for e.g.
|
48
|
-
[channel-bound cookies]).
|
49
|
-
|
50
|
-
[channel-bound cookies]: http://www.browserauth.net/channel-bound-cookies
|
51
|
-
|
52
|
-
### AuthZ
|
53
|
-
|
54
|
-
Rails::Auth ships with one primary AuthZ middleware:
|
55
|
-
|
56
|
-
* `Rails::Auth::ACL::Middleware`: support for Access Control Lists.
|
57
|
-
|
58
|
-
Access Control Lists (ACLs) let you write a single, declarative policy for
|
59
|
-
authorization in your application. ACLs are pluggable and let you write
|
60
|
-
a single policy which can authorize access using different types of
|
61
|
-
credentials.
|
62
|
-
|
63
|
-
ACLs are a declarative approach to authorization, consolidating policies
|
64
|
-
into a single file that can be easily audited by a security team without
|
65
|
-
deep understanding of the many eccentricities of Rails. These policies
|
66
|
-
provide coarse-grained authorization based on routes (as matched by
|
67
|
-
regexes) and the credentials extracted by the AuthN middleware. However,
|
68
|
-
the do not provide AuthZ which includes specific domain objects, or
|
69
|
-
policies around them.
|
70
|
-
|
71
|
-
## Comparison to other Rails/Rack auth libraries/frameworks
|
72
|
-
|
73
|
-
Below is a comparison of how Rails::Auth relates to the existing landscape
|
74
|
-
of Rails AuthN and AuthZ libraries. These are grouped into two different
|
75
|
-
categories: libraries Rails::Auth replaces, and libraries with which
|
76
|
-
Rails::Auth can be used in a complementary fashion.
|
77
|
-
|
78
|
-
### Replaces:
|
79
|
-
|
80
|
-
* [Warden]: Uses a single "opinionated" Rack middleware providing
|
81
|
-
user-centric authentication and methods that allow controllers
|
82
|
-
to imperatively interrogate the authentication context for
|
83
|
-
authorization purposes. By comparison Rails::Auth is not prescriptive
|
84
|
-
and much more flexible about credential types (supporting credentials
|
85
|
-
for both user and service clients) and uses declarative authorization
|
86
|
-
policies in the form of ACLs.
|
87
|
-
|
88
|
-
* [Devise]: A mature, flexible, expansive framework primarily intended
|
89
|
-
for user authentication. Some of the same caveats as Warden apply,
|
90
|
-
however Devise provides a framework for modeling users within a Rails
|
91
|
-
app along with common authentication flows, making it somewhat
|
92
|
-
orthogonal to what Rails::Auth provides. Rails::Auth is designed to
|
93
|
-
easily support [claims-based identity] systems where user identity
|
94
|
-
is outsourced to a separate microservice.
|
12
|
+
[microservice]: http://martinfowler.com/articles/microservices.html
|
13
|
+
[claims-based identity]: https://en.wikipedia.org/wiki/Claims-based_identity
|
95
14
|
|
96
|
-
|
15
|
+
## Description
|
97
16
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
17
|
+
Rails::Auth is a flexible library designed for both authentication (AuthN) and authorization (AuthZ) using Rack Middleware.
|
18
|
+
It [splits AuthN and AuthZ steps into separate middleware classes][design overview], using AuthN middleware to first verify
|
19
|
+
credentials (such as X.509 certificates or cookies), then authorizing the request via separate AuthZ middleware that
|
20
|
+
consumes these credentials, e.g. [access control lists][acls] (ACLs).
|
102
21
|
|
103
|
-
|
104
|
-
|
105
|
-
but provides many facilities similar to Pundit for domain object-centric
|
106
|
-
AuthZ.
|
22
|
+
Rails::Auth can be used to authenticate and authorize end users using browser cookies, service-to-service requests using
|
23
|
+
[X.509 client certificates][x509], or any other clients with credentials that have proper authenticating middleware.
|
107
24
|
|
108
|
-
[
|
109
|
-
|
110
|
-
[Pundit]: https://github.com/elabs/pundit
|
111
|
-
[CanCanCan]: https://github.com/CanCanCommunity/cancancan
|
25
|
+
Despite what the name may lead you to believe, Rails::Auth also [works well with other Rack-based frameworks][rack]
|
26
|
+
like Sinatra.
|
112
27
|
|
113
|
-
[
|
28
|
+
[design overview]: https://github.com/square/rails-auth/wiki/Design-Overview
|
29
|
+
[acls]: https://github.com/square/rails-auth/wiki/Access-Control-Lists
|
30
|
+
[x509]: https://github.com/square/rails-auth/wiki/X.509
|
31
|
+
[rack]: https://github.com/square/rails-auth/wiki/Rack-Usage
|
114
32
|
|
115
33
|
## Installation
|
116
34
|
|
@@ -128,399 +46,23 @@ Or install it yourself as:
|
|
128
46
|
|
129
47
|
$ gem install rails-auth
|
130
48
|
|
131
|
-
##
|
132
|
-
|
133
|
-
To use Rails::Auth you will need to configure the relevant AuthN and AuthZ
|
134
|
-
middleware for your app.
|
135
|
-
|
136
|
-
Rails::Auth ships with the following middleware:
|
137
|
-
|
138
|
-
* **AuthN**: `Rails::Auth::X509::Middleware`: support for authenticating
|
139
|
-
clients by their SSL/TLS client certificates.
|
140
|
-
* **AuthZ**: `Rails::Auth::ACL::Middleware`: support for authorizing requests
|
141
|
-
using Access Control Lists (ACLs).
|
142
|
-
|
143
|
-
Documentation of these middleware and how to use them is provided below.
|
144
|
-
|
145
|
-
|
146
|
-
### Controller Methods
|
147
|
-
|
148
|
-
Rails::Auth includes a module of helper methods you can use from Rails
|
149
|
-
controllers. Include them like so:
|
150
|
-
|
151
|
-
```ruby
|
152
|
-
class ApplicationController < ActionController::Base
|
153
|
-
include Rails::Auth::ControllerMethods
|
154
|
-
|
155
|
-
def x509_certificate_ou
|
156
|
-
credentials[:x509].try(:ou)
|
157
|
-
end
|
158
|
-
|
159
|
-
def current_username
|
160
|
-
# Note: Rails::Auth doesn't provide a middleware to extract this, it's
|
161
|
-
# just an example of how you could use it with your own claims-based
|
162
|
-
# identity system.
|
163
|
-
credentials[:identity_claims].try(:username)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
```
|
167
|
-
|
168
|
-
This defines the following methods:
|
169
|
-
|
170
|
-
* `#credentials`: obtain a HashWithIndifferentAccess containing all of the
|
171
|
-
credentials that Rails::Auth has extracted using its AuthN middleware.
|
172
|
-
|
173
|
-
### Access Control Lists (ACLs)
|
174
|
-
|
175
|
-
ACLs are the main tool Rails::Auth provides for AuthZ. ACLs use a set of
|
176
|
-
route-by-route matchers to control access to particular resources.
|
177
|
-
|
178
|
-
Rails::Auth encourages the use of YAML files for storing ACL definitions,
|
179
|
-
although the use of YAML is not mandatory and the corresponding object
|
180
|
-
structure output from `YAML.load` can be passed in instead. The following is
|
181
|
-
an example of an ACL definition in YAML:
|
182
|
-
|
183
|
-
```yaml
|
184
|
-
---
|
185
|
-
- resources:
|
186
|
-
- method: ALL
|
187
|
-
path: /foo/bar/.*
|
188
|
-
allow_x509_subject:
|
189
|
-
ou: ponycopter
|
190
|
-
allow_claims:
|
191
|
-
groups: ["example"]
|
192
|
-
- resources:
|
193
|
-
- method: ALL
|
194
|
-
path: /_admin/?.*
|
195
|
-
allow_claims:
|
196
|
-
groups: ["admins"]
|
197
|
-
- resources:
|
198
|
-
- method: GET
|
199
|
-
path: /internal/frobnobs/.*
|
200
|
-
allow_x509_subject:
|
201
|
-
ou: frobnobber
|
202
|
-
- resources:
|
203
|
-
- method: GET
|
204
|
-
path: /
|
205
|
-
allow_all: true
|
206
|
-
```
|
207
|
-
|
208
|
-
An ACL consists of a list of guard expressions, each of which contains a list
|
209
|
-
of resources and a set of predicates which can authorize access to those
|
210
|
-
resources. *Any* matching predicate will authorize access to any of the
|
211
|
-
resources listed for a given expression.
|
212
|
-
|
213
|
-
Resources are defined by the following constraints:
|
214
|
-
|
215
|
-
* **method**: The requested HTTP method, or `"ALL"` to allow any method
|
216
|
-
* **path**: A regular expression to match the path. `\A` and `\z` are added by
|
217
|
-
default to the beginning and end of the regex to ensure the entire path and
|
218
|
-
not a substring is matched.
|
219
|
-
* **host** (optional): a regular expression to match the `Host:` header passed
|
220
|
-
by the client. Useful if your app services traffic for more than one hostname
|
221
|
-
and you'd like to restrict ACLs by host.
|
222
|
-
|
223
|
-
Once you've defined an ACL, you'll need to create a corresponding ACL object
|
224
|
-
in Ruby and a middleware to authorize requests using that ACL. Add the
|
225
|
-
following code anywhere you can modify the middleware chain (e.g. config.ru):
|
226
|
-
|
227
|
-
```ruby
|
228
|
-
app = MyRackApp.new
|
229
|
-
|
230
|
-
acl = Rails::Auth::ACL.from_yaml(
|
231
|
-
File.read("/path/to/my/acl.yaml"),
|
232
|
-
matchers: { allow_claims: MyClaimsMatcher }
|
233
|
-
)
|
234
|
-
|
235
|
-
acl_auth = Rails::Auth::ACL::Middleware.new(app, acl: acl)
|
236
|
-
|
237
|
-
run acl_auth
|
238
|
-
```
|
239
|
-
|
240
|
-
You'll need to pass in a hash of predicate matchers that correspond to the
|
241
|
-
keys in the ACL. See the "X.509 Client Certificates" section below for how
|
242
|
-
to configure the middleware for `allow_x509_subject`.
|
243
|
-
|
244
|
-
The following predicate matchers are built-in and always available:
|
245
|
-
|
246
|
-
* **allow_all**: (options: `true` or `false`) always allow requests to the
|
247
|
-
given resources (so long as `true` is passed as the option)
|
248
|
-
|
249
|
-
Custom predicate matchers can be any Ruby class that responds to the `#match`
|
250
|
-
method. The full Rack environment is passed to `#match`. The corresponding
|
251
|
-
object from the ACL definition is passed to the class's `#initialize` method.
|
252
|
-
Here is an example of a simple custom predicate matcher:
|
253
|
-
|
254
|
-
```ruby
|
255
|
-
class MyClaimsMatcher
|
256
|
-
def initialize(options)
|
257
|
-
@options = options
|
258
|
-
end
|
259
|
-
|
260
|
-
def match(env)
|
261
|
-
claims = Rails::Auth.credentials(env)["claims"]
|
262
|
-
return false unless credential
|
263
|
-
|
264
|
-
@options["groups"].any? { |group| claims["groups"].include?(group) }
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
```
|
269
|
-
|
270
|
-
### X.509 Client Certificates
|
271
|
-
|
272
|
-
Add an `Rails::Auth::X509::Middleware` object to your Rack middleware chain to
|
273
|
-
verify X.509 client certificates (in e.g. config.ru):
|
274
|
-
|
275
|
-
```ruby
|
276
|
-
app = MyRackApp.new
|
277
|
-
|
278
|
-
acl = Rails::Auth::ACL.from_yaml(
|
279
|
-
File.read("/path/to/my/acl.yaml")
|
280
|
-
matchers: { allow_x509_subject: Rails::Auth::X509::Matcher }
|
281
|
-
)
|
282
|
-
|
283
|
-
acl_auth = Rails::Auth::ACL::Middleware.new(app, acl: acl)
|
284
|
-
|
285
|
-
x509_auth = Rails::Auth::X509::Middleware.new(
|
286
|
-
acl_auth,
|
287
|
-
ca_file: "/path/to/my/cabundle.pem"
|
288
|
-
cert_filters: { 'X-SSL-Client-Cert' => :pem },
|
289
|
-
require_cert: true
|
290
|
-
)
|
291
|
-
|
292
|
-
run x509_auth
|
293
|
-
```
|
294
|
-
|
295
|
-
The constructor takes the following parameters:
|
296
|
-
|
297
|
-
* **app**: the next Rack middleware in the chain. You'll likely want to use
|
298
|
-
an `Rails::Auth::ACL::Middleware` instance as the next middleware in the chain.
|
299
|
-
* **ca_file**: Path to the certificate authority (CA) bundle with which to
|
300
|
-
authenticate clients. This will typically be the certificates for the
|
301
|
-
internal CA(s) you use to issue X.509 certificates to internal services, as
|
302
|
-
opposed to commercial CAs typically used by browsers. Client certificates
|
303
|
-
will be ignored unless they can be verified by one of the CAs in this bundle.
|
304
|
-
* **cert_filters**: A `Hash` which configures how client certificates are
|
305
|
-
extracted from the Rack environment. You will need to configure your web
|
306
|
-
server to include the certificate in the Rack environment. See notes below
|
307
|
-
for more details.
|
308
|
-
* **require_cert**: (default `false`) require a valid client cert in order for
|
309
|
-
the request to complete. This disallows access to your app from any clients
|
310
|
-
who do not have a valid client certificate. When enabled, the middleware
|
311
|
-
will raise the `Rails::Auth::X509::CertificateVerifyFailed` exception.
|
312
|
-
|
313
|
-
When creating `Rails::Auth::ACL::Middleware`, make sure to pass in
|
314
|
-
`matchers: { allow_x509_subject: Rails::Auth::X509::Matcher }` in order to use
|
315
|
-
this predicate in your ACLs. This predicate matcher is not enabled by default.
|
316
|
-
|
317
|
-
For client certs to work, you will need to configure your web server to include
|
318
|
-
them in your Rack environment, and also configure `cert_filters` correctly to
|
319
|
-
filter and process them from the Rack environment.
|
320
|
-
|
321
|
-
For example, if you're using nginx + Passenger, you'll need to add something
|
322
|
-
like the following to your nginx configuration:
|
323
|
-
|
324
|
-
```
|
325
|
-
passenger_set_cgi_param X-SSL-Client-Cert $ssl_client_raw_cert;
|
326
|
-
```
|
327
|
-
|
328
|
-
Once the client certificate is in the Rack environment in some form, you'll
|
329
|
-
need to configure a filter object which can convert it from its Rack
|
330
|
-
environment form into an `OpenSSL::X509::Certificate` instance. There are
|
331
|
-
two built in filters you can reference as symbols to do this:
|
332
|
-
|
333
|
-
* `:pem`: parses certificates from the Privacy Enhanced Mail format
|
334
|
-
* `:java`: converts `sun.security.x509.X509CertImpl` object instances
|
335
|
-
|
336
|
-
The `cert_filters` parameter is a mapping of Rack environment names to
|
337
|
-
corresponding filters:
|
338
|
-
|
339
|
-
```ruby
|
340
|
-
cert_filters: { 'X-SSL-Client-Cert' => :pem }
|
341
|
-
```
|
342
|
-
|
343
|
-
In addition to these symbols, a filter can be any object that responds to the
|
344
|
-
`#call` method, such as a `Proc`. The following filter will parse PEM
|
345
|
-
certificates:
|
346
|
-
|
347
|
-
```ruby
|
348
|
-
cert_filters: { 'X-SSL-Client-Cert' => proc { |pem| OpenSSL::X509::Certificate.new(pem) } }
|
349
|
-
```
|
350
|
-
|
351
|
-
When certificates are recognized and verified, a `Rails::Auth::X509::Certificate`
|
352
|
-
object will be added to the Rack environment under `env["rails-auth.credentials"]["x509"]`.
|
353
|
-
This middleware will never add any certificate to the environment's credentials
|
354
|
-
that hasn't been verified against the configured CA bundle.
|
355
|
-
|
356
|
-
### Error Page Middleware
|
357
|
-
|
358
|
-
When an authorization error occurs, the `Rails::Auth::NotAuthorizedError`
|
359
|
-
exception is raised up the middleware chain. However, it's likely you would
|
360
|
-
prefer to show an error page than have an unhandled exception.
|
361
|
-
|
362
|
-
You can write your own middleware that catches `Rails::Auth::NotAuthorizedError`
|
363
|
-
if you'd like. However, this library includes two middleware for rescuing this
|
364
|
-
exception for you and displaying an error page.
|
365
|
-
|
366
|
-
#### Rails::Auth::ErrorPage::DebugMiddleware
|
367
|
-
|
368
|
-
This middleware displays a detailed error page intended to help debug authorization errors:
|
369
|
-
|
370
|
-
![Debug Error Page](https://raw.github.com/square/rails-auth/master/images/debug_error_page.png)
|
371
|
-
|
372
|
-
Please be aware this middleware leaks information about your ACL to a potential attacker.
|
373
|
-
Make sure you're ok with that information being public before using it. If you would like
|
374
|
-
to avoid leaking that information, see `Rails::Auth::ErrorPage::Middleware` below.
|
375
|
-
|
376
|
-
```ruby
|
377
|
-
app = MyRackApp.new
|
378
|
-
|
379
|
-
acl = Rails::Auth::ACL.from_yaml(
|
380
|
-
File.read("/path/to/my/acl.yaml")
|
381
|
-
matchers: { allow_x509_subject: Rails::Auth::X509::Matcher }
|
382
|
-
)
|
383
|
-
|
384
|
-
acl_auth = Rails::Auth::ACL::Middleware.new(app, acl: acl)
|
385
|
-
|
386
|
-
x509_auth = Rails::Auth::X509::Middleware.new(
|
387
|
-
acl_auth,
|
388
|
-
ca_file: "/path/to/my/cabundle.pem"
|
389
|
-
cert_filters: { 'X-SSL-Client-Cert' => :pem },
|
390
|
-
require_cert: true
|
391
|
-
)
|
392
|
-
|
393
|
-
error_page = Rails::Auth::ErrorPage::Middleware.new(x509_auth, acl: acl)
|
394
|
-
|
395
|
-
run error_page
|
396
|
-
```
|
397
|
-
|
398
|
-
#### Rails::Auth::ErrorPage::Middleware
|
399
|
-
|
400
|
-
This middleware catches `Rails::Auth::NotAuthorizedError` and renders a given static HTML file,
|
401
|
-
e.g. the 403.html file which ships with Rails. It will not give detailed errors to your users,
|
402
|
-
but it also won't leak information to an attacker.
|
403
|
-
|
404
|
-
```ruby
|
405
|
-
app = MyRackApp.new
|
406
|
-
|
407
|
-
acl = Rails::Auth::ACL.from_yaml(
|
408
|
-
File.read("/path/to/my/acl.yaml")
|
409
|
-
matchers: { allow_x509_subject: Rails::Auth::X509::Matcher }
|
410
|
-
)
|
411
|
-
|
412
|
-
acl_auth = Rails::Auth::ACL::Middleware.new(app, acl: acl)
|
413
|
-
|
414
|
-
x509_auth = Rails::Auth::X509::Middleware.new(
|
415
|
-
acl_auth,
|
416
|
-
ca_file: "/path/to/my/cabundle.pem"
|
417
|
-
cert_filters: { 'X-SSL-Client-Cert' => :pem },
|
418
|
-
require_cert: true
|
419
|
-
)
|
420
|
-
|
421
|
-
error_page = Rails::Auth::ErrorPage::Middleware.new(
|
422
|
-
x509_auth,
|
423
|
-
page_body: File.read("path/to/403.html")
|
424
|
-
)
|
425
|
-
|
426
|
-
run error_page
|
427
|
-
```
|
428
|
-
|
429
|
-
## Testing Support
|
430
|
-
|
431
|
-
### RSpec integration
|
432
|
-
|
433
|
-
Rails::Auth includes built-in matchers that allow you to write tests for your
|
434
|
-
ACLs to ensure they have the behavior you expect.
|
435
|
-
|
436
|
-
To enable RSpec support, require the following:
|
437
|
-
|
438
|
-
```ruby
|
439
|
-
require "rails/auth/rspec"
|
440
|
-
```
|
441
|
-
|
442
|
-
Below is an example of how to write an ACL spec:
|
443
|
-
|
444
|
-
```ruby
|
445
|
-
RSpec.describe "example_acl.yml", acl_spec: true do
|
446
|
-
let(:example_credentials) { x509_certificate_hash(ou: "ponycopter") }
|
447
|
-
|
448
|
-
subject do
|
449
|
-
Rails::Auth::ACL.from_yaml(
|
450
|
-
File.read("/path/to/example_acl.yml"),
|
451
|
-
matchers: { allow_x509_subject: Rails::Auth::X509::Matcher } # add your custom matchers too
|
452
|
-
)
|
453
|
-
end
|
454
|
-
|
455
|
-
describe "/path/to/resource" do
|
456
|
-
it { is_expected.to permit get_request(certificates: example_credentials) }
|
457
|
-
it { is_expected.not_to permit get_request) }
|
458
|
-
end
|
459
|
-
end
|
460
|
-
```
|
461
|
-
|
462
|
-
The following helper methods are available:
|
463
|
-
|
464
|
-
* `x509_certificate`, `x509_certificate_hash`: create instance doubles of Rails::Auth::X509::Certificate
|
465
|
-
* Request builders: The following methods build requests from the described path:
|
466
|
-
* `get_request`
|
467
|
-
* `head_request`
|
468
|
-
* `put_request`
|
469
|
-
* `post_request`
|
470
|
-
* `delete_request`
|
471
|
-
* `options_request`
|
472
|
-
* `path_request`
|
473
|
-
* `link_request`
|
474
|
-
* `unlink_request`
|
475
|
-
|
476
|
-
The following matchers are available:
|
477
|
-
|
478
|
-
* `allow_request`: allows a request with the given Rack environment, and optional credentials
|
479
|
-
|
480
|
-
### Credential Injector Middleware
|
481
|
-
|
482
|
-
`Rails::Auth::Credentials::InjectorMiddleware` allows you to arbitrarily override
|
483
|
-
the credentials in the Rack environment. This is useful for development and testing
|
484
|
-
purposes when you'd like to simulate certain credentials being in place without
|
485
|
-
e.g. actually configuring unique X.509 certificates for each scenario.
|
486
|
-
|
487
|
-
Below is an example of how you might configure Rails' `config/environments/development.rb`
|
488
|
-
and `config/environments/test.rb` files to use the middleware:
|
49
|
+
## Comparison to other Rails/Rack auth libraries/frameworks
|
489
50
|
|
490
|
-
|
51
|
+
For a comparison of Rails::Auth to other Rails auth libraries, including
|
52
|
+
complimentary libraries and those that Rails::Auth overlaps/competes with,
|
53
|
+
please see this page on the Wiki:
|
491
54
|
|
492
|
-
|
493
|
-
Rails.application.configure do
|
494
|
-
# Settings specified here will take precedence over those in config/application.rb.
|
495
|
-
[...]
|
55
|
+
[Comparison With Other Libraries](https://github.com/square/rails-auth/wiki/Comparison-With-Other-Libraries)
|
496
56
|
|
497
|
-
|
498
|
-
config.middleware.insert_before Rails::Auth::ACL::Middleware,
|
499
|
-
Rails::Auth::Credentials::InjectorMiddleware,
|
500
|
-
"user_token" => MyCredential.new(
|
501
|
-
username: "joeadmin",
|
502
|
-
claims: %w(admins),
|
503
|
-
)
|
504
|
-
end
|
505
|
-
```
|
57
|
+
## Documentation
|
506
58
|
|
507
|
-
|
59
|
+
Documentation can be found on the Wiki at: https://github.com/square/rails-auth/wiki
|
508
60
|
|
509
|
-
|
510
|
-
Rails.application.configure do
|
511
|
-
# Settings specified here will take precedence over those in config/application.rb.
|
512
|
-
[...]
|
61
|
+
YARD documentation is also available: http://www.rubydoc.info/github/square/rails-auth/master
|
513
62
|
|
514
|
-
|
515
|
-
config.x.test.credentials = {}
|
516
|
-
config.middleware.insert_before Rails::Auth::ACL::Middleware,
|
517
|
-
Rails::Auth::Credentials::InjectorMiddleware,
|
518
|
-
config.x.test.credentials
|
519
|
-
end
|
520
|
-
```
|
63
|
+
Please see the following page for how to add Rails::Auth to a Rails app:
|
521
64
|
|
522
|
-
|
523
|
-
will be injected into the Rack environment.
|
65
|
+
[Rails Usage](https://github.com/square/rails-auth/wiki/Rails-Usage)
|
524
66
|
|
525
67
|
## Contributing
|
526
68
|
|