mauth-client 4.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.travis.yml +13 -0
- data/.yardopts +4 -0
- data/CHANGELOG.md +119 -0
- data/CONTRIBUTING.md +20 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +19 -0
- data/README.md +235 -0
- data/Rakefile +7 -0
- data/doc/implementations.md +6 -0
- data/doc/mauth-client_CLI.md +59 -0
- data/doc/mauth-proxy.md +71 -0
- data/doc/mauth.yml.md +73 -0
- data/examples/Gemfile +4 -0
- data/examples/Gemfile.lock +41 -0
- data/examples/README.md +33 -0
- data/examples/config.yml +8 -0
- data/examples/get_user_info.rb +58 -0
- data/examples/mauth_key +0 -0
- data/exe/mauth-client +264 -0
- data/exe/mauth-proxy +40 -0
- data/lib/mauth/autoload.rb +8 -0
- data/lib/mauth/client.rb +487 -0
- data/lib/mauth/core_ext.rb +7 -0
- data/lib/mauth/dice_bag/mauth.rb.dice +12 -0
- data/lib/mauth/dice_bag/mauth.yml.dice +14 -0
- data/lib/mauth/dice_bag/mauth_key.dice +1 -0
- data/lib/mauth/dice_bag/mauth_templates.rb +19 -0
- data/lib/mauth/fake/rack.rb +45 -0
- data/lib/mauth/faraday.rb +87 -0
- data/lib/mauth/middleware.rb +23 -0
- data/lib/mauth/proxy.rb +77 -0
- data/lib/mauth/rack.rb +137 -0
- data/lib/mauth/request_and_response.rb +73 -0
- data/lib/mauth/version.rb +3 -0
- data/lib/mauth-client.rb +1 -0
- data/lib/rack/mauth.rb +1 -0
- data/mauth-client.gemspec +36 -0
- metadata +292 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f27f6dad85f629877f36f460275190d895e44721
|
4
|
+
data.tar.gz: 8364f1553ceac1fc4597ef129f4d79519b91377e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c1aef4d031f1b021cba88e85620cca6d5678acc5362fe6aa1b145f1b42c0b820ae41dd0bc7a7823c0f183cc0b615c7f9c6ac6cadeb64570ee4be0ad004144940
|
7
|
+
data.tar.gz: 83d8c5ae60b118c66c795e98986ef86565ed0b07ccd3ec3aa808fb77b7faa8e17ebc6e88fbd4a14b23167336fdca85f9105e3293da87265c6cf49cc63f818bd1
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
# MAuth-Client History
|
2
|
+
|
3
|
+
## v4.0.1
|
4
|
+
- Open source and publish this gem on rubygems.org, no functionality changes
|
5
|
+
|
6
|
+
## v4.0.0
|
7
|
+
- *yanked*
|
8
|
+
|
9
|
+
## v3.1.4
|
10
|
+
- Use String#bytesize method instead of Rack::Utils' one, which was removed in Rack 2.0
|
11
|
+
|
12
|
+
## v3.1.3
|
13
|
+
- Increased the default timeout when fetching keys from MAuth from 1 second to 10 seconds
|
14
|
+
- Properly honor faraday_options: timeout in mauth.yml for faraday < 0.9
|
15
|
+
|
16
|
+
## v3.1.2
|
17
|
+
- Fixed bug in Faraday call, not to raise exception when adding authenticate information to response.
|
18
|
+
|
19
|
+
## v3.1.1
|
20
|
+
- Properly require version file. Solves exception with the Faraday middleware.
|
21
|
+
|
22
|
+
## v3.1.0
|
23
|
+
- Updated `mauth.rb.dice` template to use `MAuth::Client.default_config` method and store the config in `MAUTH_CONF` constant
|
24
|
+
|
25
|
+
## v3.0.2
|
26
|
+
- Always pass a private key to the `ensure_is_private_key` method
|
27
|
+
|
28
|
+
## v3.0.1
|
29
|
+
- Use `ensure_is_private_key` in the `mauth_key` template
|
30
|
+
|
31
|
+
## v3.0.0
|
32
|
+
- Drop support for ruby 1.x
|
33
|
+
|
34
|
+
## v2.9.0
|
35
|
+
- Add a dice template for mauth initializer
|
36
|
+
|
37
|
+
## 2-8-stable
|
38
|
+
- Added an ssl_certs_path option to support JRuby applications
|
39
|
+
- Updated dice templates to ensure `rake config` raises an error in production env if required variables are missing.
|
40
|
+
|
41
|
+
## v2.7.2
|
42
|
+
- Added logging of mauth app_uuid of requester and requestee on each request
|
43
|
+
|
44
|
+
## v2.7.0
|
45
|
+
- Ability to pass custom headers into mauth-client and mauth-proxy
|
46
|
+
- Upgraded to use newest version of Faraday Middleware
|
47
|
+
- Faraday_options now only get merged to the request (previously got merged into everything)
|
48
|
+
- Syntax highlighting in hale+json output
|
49
|
+
|
50
|
+
## v2.6.4
|
51
|
+
- Less restrictive rack versioning to allow for more consumers.
|
52
|
+
- Allow verification even if intermediate web servers unescape URLs.
|
53
|
+
|
54
|
+
## v2.6.3
|
55
|
+
- Fixed bug where nil Rails.logger prevented a logger from being built.
|
56
|
+
|
57
|
+
## v2.6.2
|
58
|
+
- Added templates for dice_bag, now rake config:generate_all will create mauth config files when you include this gem.
|
59
|
+
|
60
|
+
## v2.6.1
|
61
|
+
- Imported documentation from Medinet into the project's doc directory
|
62
|
+
- Add Shamus
|
63
|
+
|
64
|
+
## v2.6.0
|
65
|
+
- CLI option --no-ssl-verify disables SSL verification
|
66
|
+
- Syntax highlighting with CodeRay colorizes request and response bodies of recognized media types
|
67
|
+
- MAuth::Proxy class now lives in lib, in mauth/proxy, and may be used as a rack application
|
68
|
+
- mauth-proxy executable recognizes --no-authenticate option for responses
|
69
|
+
- MAuth::Proxy bugfix usage of REQUEST_URI; use Rack::Request#fullpath instead
|
70
|
+
|
71
|
+
## v2.5.0
|
72
|
+
- MAuth::Rack::RequestAuthenticator middleware responds with json (instead of text/plain) for inauthentic requests and requests which it is unable to authenticate
|
73
|
+
- Added MAuth::Client.default_config method
|
74
|
+
- Added mauth-proxy executable
|
75
|
+
- Faraday middlewares are registered with Faraday
|
76
|
+
- Rack middleware correctly handles Content-Length with HEAD requests
|
77
|
+
- MAuth::Client raises MAuth::Client::ConfigurationError instead of ArgumentError or RuntimeError as appropriate
|
78
|
+
|
79
|
+
## v2.4.0
|
80
|
+
- Colorized output from the mauth-client CLI
|
81
|
+
- Add --content-type option to CLI
|
82
|
+
- CLI rescues and prints MAuth errors instead of them bubbling up to the interpreter
|
83
|
+
- Improved method documentation
|
84
|
+
- Fix default null logger on windows where /dev/null is not available
|
85
|
+
- Improve error logging
|
86
|
+
|
87
|
+
## v2.3.0
|
88
|
+
- When authentication headers are missing, the previous message ("No x-mws-time present") is replaced by the somewhat more informative "Authentication Failed. No mAuth signature present; X-MWS-Authentication header is blank."
|
89
|
+
- More informative help messages from mauth-client CLI
|
90
|
+
- CLI sets a user-agent
|
91
|
+
- Handling timeout errors is fixed (previously only handled connection errors)
|
92
|
+
- Middleware MAuth::Rack::RequestAuthenticationFaker for testing
|
93
|
+
- More and better specs
|
94
|
+
|
95
|
+
## v2.2.0
|
96
|
+
- Fixes an issue where requests which have a body and are not PUT or POST were not being correctly signed in rack middleware
|
97
|
+
- Improves the CLI, adding command-line options --[no-]authenticate to decide whether to authenticate responses, and --[no-]verbose to decide whether to dump the entire request and response, or just the response body. and --help to
|
98
|
+
Remind you.
|
99
|
+
- Fixes mauth-client CLI being registered as an executable in the gemspec - now it should be possible to just `bundle exec mauth-client` if you have the gem bundle installed (or just `mauth-client` if you have it installed as a regular gem, but that's less straightforward)
|
100
|
+
- New middleware MAuth::Rack::RequestAuthenticatorNoAppStatus - same as MAuth::Rack::RequestAuthenticator, but does not authenticate /app_status. this will be the most commonly used case, so made it its own middleware.
|
101
|
+
- Middleware responds to HEAD requests correctly in error conditions, not including a response body
|
102
|
+
- Drops backports dependency (Ben has found some issues with this gem, and it was easier to drop the depedency entirely than figure out whether these issues affected mauth-client and if it could be fixed)
|
103
|
+
- Fix issue with remote authentication against the currently-deployed mauth service with a request signed by a nonexistent app_uuid
|
104
|
+
|
105
|
+
## v2.1.1
|
106
|
+
- Fix an issue in a case where the rack.input is not rewound before mauth-client attempts to read it
|
107
|
+
|
108
|
+
## v2.1.0
|
109
|
+
- MAuth::Client handles the :private_key_file, so you can remove from your application the bit that does that - this bit can be deleted:
|
110
|
+
```
|
111
|
+
if mauth_conf['private_key_file']
|
112
|
+
mauth_conf['private_key'] = File.read(mauth_conf['private_key_file'])
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
- Autoloads are in place so that once you require 'mauth/client', you should not need to require mauth/rack, mauth/faraday, or mauth/request_and_response.
|
117
|
+
|
118
|
+
## v2.0.0
|
119
|
+
- Rewrite combining the mauth_signer and rack-mauth gems
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
## General Information
|
4
|
+
|
5
|
+
* Check out the latest develop to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
6
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
7
|
+
* Fork the project
|
8
|
+
* Start a feature/bugfix branch
|
9
|
+
* Commit and push until you are happy with your contribution
|
10
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
11
|
+
|
12
|
+
## Running Tests
|
13
|
+
|
14
|
+
To run tests, first run `bundle install`.
|
15
|
+
|
16
|
+
Next, run the tests with an appropriate mauth config file, typically this is done by passing the provided one using an environment variable:
|
17
|
+
|
18
|
+
```
|
19
|
+
MAUTH_CONFIG_YML=`pwd`/spec/config_root/config/mauth.yml bundle exec rspec
|
20
|
+
```
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2016 Medidata Solutions Worldwide
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,235 @@
|
|
1
|
+
# MAuth Client
|
2
|
+
[![Build Status](https://travis-ci.org/mdsol/mauth-client-ruby.svg)](https://travis-ci.org/mdsol/mauth-client-ruby)
|
3
|
+
|
4
|
+
This gem consists of MAuth::Client, a class to manage the information needed to both sign and authenticate requests
|
5
|
+
and responses, and middlewares for Rack and Faraday which leverage the client's capabilities.
|
6
|
+
|
7
|
+
MAuth Client exists in a variety of languages (.Net, Go, R etc.), see the [implementations list](doc/implementations.md) for more info.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'mauth-client'
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
```
|
19
|
+
$ bundle
|
20
|
+
```
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
```
|
24
|
+
$ gem install mauth-client
|
25
|
+
```
|
26
|
+
|
27
|
+
|
28
|
+
## Configuration
|
29
|
+
|
30
|
+
MAuth is typically configured by a yaml file, [mauth.yml](doc/mauth.yml.md) - see its page for more documentation.
|
31
|
+
This is simply loaded and passed to either middleware or directly to a MAuth::Client instance.
|
32
|
+
See the documentation for [MAuth::Client#initialize](lib/mauth/client.rb) for more details of what it accepts. Usually you will want:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
mauth_config = MAuth::Client.default_config
|
36
|
+
```
|
37
|
+
|
38
|
+
The `.default_config` method takes a number of options to tweak its expectations regarding defaults. See the
|
39
|
+
documentation for [MAuth::Client.default_config](lib/mauth/client.rb) for details.
|
40
|
+
|
41
|
+
The `private_key` and `app_uuid` (which go in mauth.yml) enable local authentication (see section [Local Authentication](#local-authentication) below).
|
42
|
+
They’ll only work if the `app_uuid` has been stored in MAuth with a public key corresponding to the `private_key` in mauth.yml.
|
43
|
+
|
44
|
+
If you do not have an `app_uuid` and keypair registered with the mauth service, you can use mauth's remote request authentication by omitting those fields.
|
45
|
+
MAuth-Client will make a call to MAuth for every request in order to authenticate remotely.
|
46
|
+
Remote authentication therefore requires more time than local authentication.
|
47
|
+
You will not be able to sign your responses without an `app_uuid` and a private key, so `MAuth::Rack::ResponseSigner` cannot be used.
|
48
|
+
|
49
|
+
The `mauth_baseurl` and `mauth_api_version` are required in mauth.yml.
|
50
|
+
These tell the MAuth Client where and how to communicate with the MAuth service.
|
51
|
+
|
52
|
+
|
53
|
+
## Rack Middleware Usage
|
54
|
+
|
55
|
+
MAuth Client provides a middleware for request authentication and response verification in mauth/rack.
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
require 'mauth/rack'
|
59
|
+
```
|
60
|
+
|
61
|
+
If you are using other rack middlewares, the MAuth middleware MUST come FIRST in the stack of middlewares.
|
62
|
+
This means it is closest to the HTTP layer, furthest from the application.
|
63
|
+
If any other middlewares which modify the incoming request or outgoing response lie between the HTTP layer and the MAuth middleware, incoming requests will probably fail to authenticate and outgoing response signatures will be invalid (and fail when the requester tries to authenticate them).
|
64
|
+
|
65
|
+
Using these middlewares in rails consists of calls to `config.middleware.use` in the appropriate place (see [the Rails Guides](http://guides.rubyonrails.org/rails_on_rack.html) for more info).
|
66
|
+
|
67
|
+
Using the `MAuth::Rack::ResponseSigner` middleware is optional, but highly recommended.
|
68
|
+
If used, this should come before the `MAuth::Rack::RequestAuthenticator` middleware.
|
69
|
+
The ResponseSigner can be used ONLY if you have an `app_uuid` and `private_key` specified in your mauth configuration.
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
config.middleware.use MAuth::Rack::ResponseSigner, mauth_config
|
73
|
+
```
|
74
|
+
|
75
|
+
Then request authentication:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
config.middleware.use MAuth::Rack::RequestAuthenticator, mauth_config
|
79
|
+
```
|
80
|
+
|
81
|
+
However, assuming you have a route `/app_status`, you probably want to skip request authentication for that.
|
82
|
+
There is a middleware (`RequestAuthenticatorNoAppStatus`) to make that easier:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
config.middleware.use MAuth::Rack::RequestAuthenticatorNoAppStatus, mauth_config
|
86
|
+
```
|
87
|
+
|
88
|
+
You may want to configure other conditions in which to bypass MAuth authentication.
|
89
|
+
The middleware takes an option on the `:should_authenticate_check` key, which is a ruby proc that is passed to the request's rack env and must result in a boolean.
|
90
|
+
If the result is true(ish), the middleware will authenticate the incoming request; if false, it will not.
|
91
|
+
The `:should_authenticate_check` parameter is OPTIONAL.
|
92
|
+
If omitted, all incoming requests will be authenticated.
|
93
|
+
|
94
|
+
Here are a few example `:should_authenticate_check` procs:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
mauth_config[:should_authenticate_check] = proc do |env|
|
98
|
+
env['REQUEST_METHOD'] == 'GET'
|
99
|
+
end
|
100
|
+
config.middleware.use MAuth::Rack::RequestAuthenticator, mauth_config
|
101
|
+
```
|
102
|
+
|
103
|
+
Above, env is a hash of request parameters; this hash is generated by Rack.
|
104
|
+
The above proc will force the middleware to authenticate only GET requests.
|
105
|
+
|
106
|
+
|
107
|
+
Another example:
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
mauth_config[:should_authenticate_check] = proc do |env|
|
111
|
+
env['PATH_INFO'] == '/studies.json'
|
112
|
+
end
|
113
|
+
config.middleware.use MAuth::Rack::RequestAuthenticator, mauth_config
|
114
|
+
```
|
115
|
+
|
116
|
+
The above proc will force the rack middleware to authenticate only requests to the "/studies.json" path.
|
117
|
+
To authenticate a group of related URIs, considered matching `env['PATH_INFO']` with one or more regular expressions.
|
118
|
+
|
119
|
+
The configuration passed to the middlewares in the above examples (`mauth_config`) is used create a new instance of `MAuth::Client`.
|
120
|
+
If you are managing an MAuth::Client of your own for some reason, you can pass that in on the key `:mauth_client => your_client`, and omit any other MAuth::Client configuration.
|
121
|
+
`:should_authenticate_check` is handled by the middleware and should still be specified alongside `:mauth_client`, if you are using it.
|
122
|
+
|
123
|
+
When the request authentication middleware determines that a request is inauthentic, it will not call the application and will respond with a 401 status code along with an error, expressed in JSON
|
124
|
+
(Content-Type: application/json) with the following value:
|
125
|
+
```
|
126
|
+
{ "errors": { "mauth": ["Unauthorized"] } }
|
127
|
+
```
|
128
|
+
Successfully authenticated requests will be passed to the application, as will requests for which the `:should_authenticate_check` condition is false.
|
129
|
+
|
130
|
+
If the middleware is unable to authenticate the request because MAuth is unavailable and so cannot serve public keys, it responds with a 500 status code and an error expressed in JSON with the value:
|
131
|
+
```
|
132
|
+
{ "errors": { "mauth": ["Could not determine request authenticity"] } }
|
133
|
+
```
|
134
|
+
|
135
|
+
## Examples
|
136
|
+
|
137
|
+
Putting all this together, here are typical examples (in rails you would put that code in an initializer):
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
mauth_config = MAuth::Client.default_config
|
141
|
+
require 'mauth/rack'
|
142
|
+
config.middleware.use MAuth::Rack::ResponseSigner, mauth_config
|
143
|
+
config.middleware.use MAuth::Rack:: RequestAuthenticatorNoAppStatus, mauth_config
|
144
|
+
```
|
145
|
+
|
146
|
+
With `:should_authenticate_check`:
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
mauth_config = MAuth::Client.default_config
|
150
|
+
require 'mauth/rack'
|
151
|
+
config.middleware.use MAuth::Rack::ResponseSigner, mauth_config
|
152
|
+
# authenticate all requests which pass the some_condition_of check and aren't /app_status with MAuth
|
153
|
+
mauth_config[:should_authenticate_check] = proc do |env|
|
154
|
+
some_condition_of(env)
|
155
|
+
end
|
156
|
+
config.middleware.use MAuth::Rack:: RequestAuthenticatorNoAppStatus, mauth_config
|
157
|
+
```
|
158
|
+
|
159
|
+
## Fake middleware
|
160
|
+
|
161
|
+
For testing purposes, you may wish to use middleware which does not perform actual authentication.
|
162
|
+
MAuth provides this, as `MAuth::Rack::RequestAuthenticationFaker`.
|
163
|
+
Requests are still checked for the presence of an MAuth signature - this is necessary as many applications rely on the `app_uuid` identified in the signature, so it cannot be ignored entirely.
|
164
|
+
However, the validity of the public key is not checked in the MAuth service, and the authenticity of the request is not verified by its signature.
|
165
|
+
|
166
|
+
This example code may augment the above examples to disable authentication in test mode:
|
167
|
+
|
168
|
+
```ruby
|
169
|
+
require 'mauth/fake/rack'
|
170
|
+
authenticator = Rails.env != 'test' ? MAuth::Rack::RequestAuthenticator : MAuth::Rack::RequestAuthenticationFaker
|
171
|
+
config.middleware.use authenticator, mauth_config
|
172
|
+
```
|
173
|
+
|
174
|
+
## Faraday Middleware Usage
|
175
|
+
|
176
|
+
If you are making outgoing HTTP requests using Faraday, adding MAuth Faraday middleware is much the same as adding rack middleware.
|
177
|
+
Building your connection will look like:
|
178
|
+
|
179
|
+
```ruby
|
180
|
+
Faraday.new(some_args) do |builder|
|
181
|
+
builder.use MAuth::Faraday::RequestSigner, mauth_config
|
182
|
+
builder.use MAuth::Faraday::ResponseAuthenticator, mauth_config
|
183
|
+
builder.adapter Faraday.default_adapter
|
184
|
+
end
|
185
|
+
```
|
186
|
+
|
187
|
+
The Faraday middleware MUST come LAST in the stack of middleware.
|
188
|
+
As with the rack middleware, this means it will be right next to the HTTP adapter.
|
189
|
+
|
190
|
+
Only use the `MAuth::Faraday::ResponseAuthenticator` middleware if you are expecting the service you are communicating with to sign its responses (all services which are aware of MAuth _should_ be doing this).
|
191
|
+
|
192
|
+
`mauth_config` is the same as in Rack middleware, and as with the Rack middleware is used to initialize a `MAuth::Client` instance.
|
193
|
+
Also as with the Rack middleware, you can pass in a `MAuth::Client` instance you are using yourself on the `:mauth_client` key, and omit any other configuration.
|
194
|
+
|
195
|
+
Behavior is likewise similar to rack: if a `private_key` and `app_uuid` are specified, then ResponseAuthenticator will authenticate locally (see [Local Authentication](#local-authentication) below); if not, then it will go to the
|
196
|
+
mauth service to authenticate.
|
197
|
+
`MAuth::Faraday::RequestSigner` cannot be used without a `private_key` and `app_uuid`.
|
198
|
+
|
199
|
+
If a response which does not appear to be authentic is received by the `MAuth::Faraday::ResponseAuthenticator` middleware, a `MAuth::InauthenticError` will be raised.
|
200
|
+
|
201
|
+
If the MAuth service cannot be reached, and therefore the authenticity of a response cannot be verified by ResponseAuthenticator, then a `MAuth::UnableToAuthenticateError` will be raised.
|
202
|
+
|
203
|
+
## Other Request and Response signing
|
204
|
+
|
205
|
+
If you are not using Faraday, you will need to sign your own requests.
|
206
|
+
|
207
|
+
Instantiate a `MAuth::Client` with the same configuration as the middlewares, as documented on [MAuth::Client#initialize](lib/mauth/client.rb).
|
208
|
+
We'll call this `mauth_client`.
|
209
|
+
|
210
|
+
`mauth_client` has a method `#signed_headers` which takes either a `MAuth::Request` or `MAuth::Response` object, and generates HTTP headers which can be added to the request or response to indicate authenticity.
|
211
|
+
Create a `MAuth::Request` object from the information in your HTTP request, whatever its form:
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
require 'mauth/request_and_response'
|
215
|
+
request = MAuth::Request.new(verb: my_verb, request_url: my_request_url, body: my_body)
|
216
|
+
```
|
217
|
+
`mauth_client.signed_headers(request)` will then return mauth headers which you can apply to your request.
|
218
|
+
|
219
|
+
## Local Authentication
|
220
|
+
|
221
|
+
When doing local authentication, the mauth client will periodically fetch and cache public keys from MAuth.
|
222
|
+
Each public key will be cached locally for 60 seconds.
|
223
|
+
Applications which connect frequently to the app will benefit most from this caching strategy.
|
224
|
+
When fetching public keys from MAuth, the following rules apply:
|
225
|
+
|
226
|
+
1. If MAuth returns the public key for a given `app_uuid`, MAuth-Client will refresh its local cache with this new public key.
|
227
|
+
2. If MAuth cannot find the public key for a given `app_uuid` (i.e. returns a 404 status code), MAuth-Client will remove the corresponding public key from its local cache and authentication of any message from the application with this public key will fail as a consequence.
|
228
|
+
3. If the request to MAuth times out or MAuth returns a 500 status code, the requested public key will not be removed from local MAuth-Client cache (if it exists there in the first place).
|
229
|
+
The cached version will continue to be used for local authentication until MAuth::Client is able to again communicate with MAuth.
|
230
|
+
|
231
|
+
## Warning
|
232
|
+
|
233
|
+
During development classes are typically not cached in Rails applications.
|
234
|
+
If this is the case, be aware that the MAuth-Client middleware object will be instantiated anew for each request;
|
235
|
+
this will cause applications performing local authentication to fetch public keys before each request is authenticated.
|
data/Rakefile
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
# MAuth-Client implementations
|
2
|
+
|
3
|
+
- .Net: [mauth-client-dotnet](https://github.com/mdsol/mauth-client-dotnet)
|
4
|
+
- Go (golang): [go-mauth-client](https://github.com/mdsol/go-mauth-client)
|
5
|
+
- R: [RMauthClient](https://github.com/mdsol/RMauthClient)
|
6
|
+
- Ruby: [mauth-client-ruby](https://github.com/mdsol/mauth-client-ruby)
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# MAuth-Client CLI Tool
|
2
|
+
|
3
|
+
MAuth-Client provides a Command Line Interface (CLI) tool to make MAuth-signed requests and verify MAuth-signed responses.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
The MAuth-Client CLI is part of the MAuth Client gem, refer to [the README](../README.md#installation) for installation instructions.
|
8
|
+
|
9
|
+
## Configuration
|
10
|
+
|
11
|
+
The CLI is configured with a [mauth.yml](./mauth.yml.md) file - see its page for instructions.
|
12
|
+
|
13
|
+
The MAuth-Client CLI tool looks for the configuration file in several places:
|
14
|
+
|
15
|
+
- if an environment variable `MAUTH_CONFIG_YML` points to an existing file, mauth-client will use that file if it exists.
|
16
|
+
- if you have a file `~/.mauth_config.yml` then it will use that. This is useful if you have your own mauth key.
|
17
|
+
- if you are in a directory relative to which a config/mauth.yml exists, it will use that. This is useful if you are working in a project which uses mauth and has a key configured.
|
18
|
+
- if you are in a directory in which a file mauth.yml exists, it will use that.
|
19
|
+
|
20
|
+
mauth.yml is expected to contain, at the top level, an environment key or keys.
|
21
|
+
mauth-client checks environment variables `RAILS_ENV` and `RACK_ENV` to determine the environment, and defaults to 'development' if none of these are set.
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
The mauth-client executable should be available with `bundle exec`, once it has been installed in your Gemfile.
|
26
|
+
If you installed the gem manually, you may not need to run `bundle exec`.
|
27
|
+
|
28
|
+
```
|
29
|
+
$ bundle exec mauth-client --help
|
30
|
+
Usage: mauth-client [options] <verb> <url> [body]
|
31
|
+
-v, --[no-]verbose Run verbosely - output is like curl -v (this is the default)
|
32
|
+
-q Run quietly - only outputs the response body (same as --no-verbose)
|
33
|
+
--[no-]authenticate Authenticate the response received
|
34
|
+
--[no-]color Color the output (defaults to color if the output device is a TTY)
|
35
|
+
-t, --content-type CONTENT-TYPE Sets the Content-Type header of the request
|
36
|
+
-H, --header LINE accepts a json string of additional headers to included. IE 'cache-expirey: 10, other: value
|
37
|
+
--no-ssl-verify Disables SSL verification - use cautiously!
|
38
|
+
```
|
39
|
+
|
40
|
+
Examples:
|
41
|
+
|
42
|
+
```
|
43
|
+
bundle exec mauth-client GET https://eureka-innovate.imedidata.com/v1/apis
|
44
|
+
```
|
45
|
+
|
46
|
+
```
|
47
|
+
bundle exec mauth-client GET https://eureka-innovate.imedidata.com/v1/deployments
|
48
|
+
```
|
49
|
+
|
50
|
+
```
|
51
|
+
bundle exec mauth-client POST https://eureka-innovate.imedidata.com/v1/deployments '{"baseURI": "https://cupcakes.imedidata.com", "stage": "production", "apis": [{"name": "cupcakes", "version": "v1.0.0"}]}'
|
52
|
+
```
|
53
|
+
|
54
|
+
## Output
|
55
|
+
|
56
|
+
MAuth-Client CLI's default output is designed to look like the output of `curl -v`.
|
57
|
+
It includes all headers, body, and other components of the http request.
|
58
|
+
This can be suppressed with the `-q` (quiet) option, in which case only the response body will be output.
|
59
|
+
The normal output (not the quiet version) is colorized by default if connected to a tty device (e.g. a terminal).
|
data/doc/mauth-proxy.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# mauth-proxy executable
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
|
5
|
+
mauth-proxy is a command-line tool to forward requests to a service, signing each one with a MAuth signature and verifying responses from the service.
|
6
|
+
|
7
|
+
mauth-proxy wraps a Rack server, which listens on localhost (external connections are not allowed, for security).
|
8
|
+
mauth-proxy takes each request, signs it with a specified MAuth configuration, and makes a request to the given service.
|
9
|
+
The response from the service is authenticated with MAuth, and is returned as the response to the original request.
|
10
|
+
|
11
|
+
The intent is to allow users to point any HTTP or REST client they care to use at a service which authenticates with MAuth, without the client needing to know how to generate MAuth signatures or authenticate MAuth-signed responses.
|
12
|
+
|
13
|
+
The proxy has two modes: single-target and browser proxy mode. In browser proxy mode, it can be configured as a HTTP proxy in a browser and will direct the requests to any URL in the request while signing requests to URLs that are listed in the command line.
|
14
|
+
In single-target mode, all requests will be directed to the server specified in the command line.
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
Single target mode:
|
19
|
+
```
|
20
|
+
$ bundle exec mauth-proxy -p 3452 https://eureka.imedidata.com/
|
21
|
+
```
|
22
|
+
|
23
|
+
This will launch a rack server, listening on port 3452.
|
24
|
+
When a request is made to this server on a particular path - say `http://localhost:3452/v1/apis`, then mauth-proxy will make a mauth-signed request to `https://eureka.imedidata.com/v1/apis`, then authenticate the response and return that response to the original request.
|
25
|
+
|
26
|
+
Browser proxy mode:
|
27
|
+
```
|
28
|
+
$ bundle exec mauth-proxy -p 3452 --browser_proxy http://localhost:3000 http://localhost:9292
|
29
|
+
```
|
30
|
+
|
31
|
+
For this mode, add localhost:3452 in your browser's proxy configuration and access the service you want to use.
|
32
|
+
If the beginning of the requested URL matches one of the URLs you specified, it will be signed and authenticated.
|
33
|
+
|
34
|
+
|
35
|
+
## Options
|
36
|
+
|
37
|
+
The location of the mauth configuration can be specified or infered automatically, see the [MAuth-Client CLI Tool doc](./mauth-client_CLI.md#configuration) for more details.
|
38
|
+
|
39
|
+
The last command-line argument MUST be a target URI to which requests will be forwarded.
|
40
|
+
|
41
|
+
The `--no-authenticate` option disables response authentication from the target service.
|
42
|
+
|
43
|
+
The `--browser_proxy` option switches to browser proxy mode and is intended to be used when the proxy is used in conjunction with a web browser that is set to use this proxy.
|
44
|
+
|
45
|
+
The `--header` Accepts a [key]:[value] header definition to include, e.g. -h "Accept:application/json". It can be used multiple times for multiple headers.
|
46
|
+
|
47
|
+
All other options are passed along to rack.
|
48
|
+
Available options can be viewed by running rackup -h, and are also listed below:
|
49
|
+
|
50
|
+
```
|
51
|
+
Ruby options:
|
52
|
+
-e, --eval LINE evaluate a LINE of code
|
53
|
+
-d, --debug set debugging flags (set $DEBUG to true)
|
54
|
+
-w, --warn turn warnings on for your script
|
55
|
+
-I, --include PATH specify $LOAD_PATH (may be used more than once)
|
56
|
+
-r, --require LIBRARY require the library, before executing your script
|
57
|
+
|
58
|
+
Rack options:
|
59
|
+
-s, --server SERVER serve using SERVER (webrick/mongrel)
|
60
|
+
-o, --host HOST listen on HOST (default: 0.0.0.0)
|
61
|
+
-p, --port PORT use PORT (default: 9292)
|
62
|
+
-O NAME[=VALUE], pass VALUE to the server as option NAME. If no VALUE, sets it to true. Run 'rackup -s SERVER -h' to get a list of options for SERVER
|
63
|
+
--option
|
64
|
+
-E, --env ENVIRONMENT use ENVIRONMENT for defaults (default: development)
|
65
|
+
-D, --daemonize run daemonized in the background
|
66
|
+
-P, --pid FILE file to store PID (default: rack.pid)
|
67
|
+
|
68
|
+
Common options:
|
69
|
+
-h, -?, --help Show this message
|
70
|
+
--version Show version
|
71
|
+
```
|
data/doc/mauth.yml.md
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# mauth.yml
|
2
|
+
|
3
|
+
The conventional way to configure MAuth-Client for your project is through a YAML file which lives in your project at `config/mauth.yml`.
|
4
|
+
It is keyed on environment, and for the most part its contents are passed directly to instantiate an MAuth::Client.
|
5
|
+
See the documentation for [MAuth::Client#initialize](../lib/mauth/client.rb) for more details of what it accepts.
|
6
|
+
|
7
|
+
## Generating keys
|
8
|
+
|
9
|
+
To generate a private key (`mauth_key`) and its public counterpart (`mauth_key.pub`) run:
|
10
|
+
|
11
|
+
```
|
12
|
+
openssl genrsa -out mauth_key 2048
|
13
|
+
openssl rsa -in mauth_key -pubout -out mauth_key.pub
|
14
|
+
```
|
15
|
+
|
16
|
+
## Format
|
17
|
+
|
18
|
+
```yaml
|
19
|
+
common: &common
|
20
|
+
mauth_baseurl: https://mauth-innovate.imedidata.com
|
21
|
+
mauth_api_version: v1
|
22
|
+
app_uuid: 123we997-0333-44d8-8fCf-5dd555c5bd51
|
23
|
+
private_key: |
|
24
|
+
-----BEGIN RSA PRIVATE KEY-----
|
25
|
+
AIIEowIBAAKCAQEAwLYWYcKrCAl7uWVlkwzBcBXRiRREqGYLXEnRGgDrlqbY+lDg
|
26
|
+
gwMNga3ylckui/rTUZhtefx1MLtxgnTGiil45eleoJgjdfsOO5yXzUA46KW0cuL4
|
27
|
+
...
|
28
|
+
oEKe4QKBgFNbVJp3Zut83MzpN4Zu7/wZ/+q9ds9WMMxWb4hUugKQTPjsgj+8tCqa
|
29
|
+
SIY2exfsy7Y8NoOnBPlGiXKhgaF21T8kqV9C7R6OAuP0U6CgMJnINx/UjozvBENH
|
30
|
+
Ux45QdvRd6vai8nHp7AgV7rr55SxXAZVgATll84uBUpfpmC6YK/j
|
31
|
+
-----END RSA PRIVATE KEY-----
|
32
|
+
|
33
|
+
production:
|
34
|
+
<<: *common
|
35
|
+
development:
|
36
|
+
<<: *common
|
37
|
+
test:
|
38
|
+
<<: *common
|
39
|
+
```
|
40
|
+
|
41
|
+
Optionally you can load the private key from a file:
|
42
|
+
|
43
|
+
```yaml
|
44
|
+
common: &common
|
45
|
+
mauth_baseurl: https://mauth-innovate.imedidata.com
|
46
|
+
mauth_api_version: v1
|
47
|
+
app_uuid: 123we997-0333-44d8-8fCf-5dd555c5bd51
|
48
|
+
private_key_file: config/my_mauth_private.key
|
49
|
+
|
50
|
+
production:
|
51
|
+
<<: *common
|
52
|
+
development:
|
53
|
+
<<: *common
|
54
|
+
test:
|
55
|
+
<<: *common
|
56
|
+
```
|
57
|
+
|
58
|
+
## Configuration options
|
59
|
+
|
60
|
+
- `private_key` - Required for signing and for authenticating responses. May be omitted if only remote authentication of requests is being performed.
|
61
|
+
- `private_key_file` - May be used instead of `private_key`, mauth-client will load the file instead.
|
62
|
+
- `app_uuid` - Required in the same circumstances where a `private_key` is required.
|
63
|
+
- `mauth_baseurl` - Required for authentication but not for signing. Needed for local authentication to retrieve public keys and for remote authentication. Usually this is `https://mauth.imedidata.com` for production.
|
64
|
+
- `mauth_api_version` - Required for authentication but not for signing. only `v1` exists as of this writing.
|
65
|
+
|
66
|
+
## Usage in your application
|
67
|
+
|
68
|
+
Load mauth.yml, merge in any other configuration that is needed for your usage, and pass the config along to instantiate a `MAuth::Client` or a middleware.
|
69
|
+
See the [README](../README.md) for more detail.
|
70
|
+
|
71
|
+
## Usage in MAuth-Client executables (mauth-client, mauth-proxy)
|
72
|
+
|
73
|
+
See the [MAuth-Client CLI Tool doc](./mauth-client_CLI.md#configuration).
|
data/examples/Gemfile
ADDED