rodauth-oauth 0.0.5 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +180 -5
- data/README.md +45 -21
- data/lib/generators/roda/oauth/templates/db/migrate/create_rodauth_oauth.rb +8 -5
- data/lib/rodauth/features/oauth.rb +514 -416
- data/lib/rodauth/features/oauth_http_mac.rb +6 -10
- data/lib/rodauth/features/oauth_jwt.rb +178 -74
- data/lib/rodauth/features/oauth_saml.rb +104 -0
- data/lib/rodauth/features/oidc.rb +399 -0
- data/lib/rodauth/oauth/database_extensions.rb +73 -0
- data/lib/rodauth/oauth/ttl_store.rb +1 -1
- data/lib/rodauth/oauth/version.rb +1 -1
- data/templates/authorize.str +34 -0
- data/templates/client_secret_field.str +4 -0
- data/templates/description_field.str +4 -0
- data/templates/homepage_url_field.str +4 -0
- data/templates/name_field.str +4 -0
- data/templates/new_oauth_application.str +10 -0
- data/templates/oauth_application.str +11 -0
- data/templates/oauth_applications.str +14 -0
- data/templates/oauth_tokens.str +49 -0
- data/templates/redirect_uri_field.str +4 -0
- data/templates/scope_field.str +10 -0
- metadata +24 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b09ecfc1d3a8ee0f5b890620baa14ca6d847362bf38dd158e02bd2c8ebfc204e
|
4
|
+
data.tar.gz: 89f0e82d7721f7ee175b1c53b7b3e0cc534e6983fe37dfc02e433df77b58225d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d00a178f561ddecacff0587e1120b68bb22cd10b76b106b00f41167ba9c8bd8b2b8958fd629588924e502be8c947a81d3722102038cd329c006f4b4daf6efada
|
7
|
+
data.tar.gz: 328542ba8ce7ef8e8f605056a9a8cbf6599136232d93f7246b13fe037ebc07225e2051b3ee454eb90ec4ae480e2b493d662d1cbbcd0ae5cc7e57a0ff29b10696
|
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,174 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
-
### 0.0
|
5
|
+
### 0.4.0
|
6
|
+
|
7
|
+
### Features
|
8
|
+
|
9
|
+
* A new method, `get_additional_param(account, claim)`, is now exposed; this method will be called whenever non-OIDC scopes are requested in the emission of the ID token.
|
10
|
+
|
11
|
+
* The `form_post` response is now supported, either by passing the `response_mode=form_post` request param in the authorization URL, or by setting `oauth_response_mode "form_post"` option. This improves the overall security of an Authorization server even more, as authorization codes are sent to client applications via a POST request to the redirect URI.
|
12
|
+
|
13
|
+
|
14
|
+
### Improvements
|
15
|
+
|
16
|
+
* For the OIDC `address` scope, proper claims are now emitted as per the standard, i.e. the "formatted", "street_address", "locality", "region", "postal_code", "country". These will be the ones referenced in the `get_oidc_param` method.
|
17
|
+
|
18
|
+
### Bugfixes
|
19
|
+
|
20
|
+
* The rails templates were missing declarations from a few params, which made some of the flows (the PKCE for example) not work out-of-the box;
|
21
|
+
* rails tests were silently not running in CI;
|
22
|
+
* The CI suite was revamped, so that all Oauth tests would be run under rails as well. All versions from rails equal or above 5.0 are now targeted;
|
23
|
+
|
24
|
+
### 0.3.0
|
25
|
+
|
26
|
+
#### Features
|
27
|
+
|
28
|
+
* `oauth_refresh_token_protection_policy` is a new option, which can be used to set a protection policy around usage of refresh tokens. By default it's `none`, for backwards-compatibility. However, when set to `rotation`, refresh tokens will be "use-once", i.e. a token refresh request will generate a new refresh token. Also, refresh token requests performed with already-used refresh tokens will be interpreted as a security breach, i.e. all tokens linked to the compromised refresh token will be revoked.
|
29
|
+
|
30
|
+
#### Improvements
|
31
|
+
|
32
|
+
|
33
|
+
* Support for the OIDC authorize [`prompt` parameter](https://openid.net/specs/openid-connect-core-1_0.html) (sectionn 3.1.2.1). It supports the `none`, `login` and `consent` out-of-the-box, while providing support for `select-account` when paired with [rodauth-select-account, a rodauth feature to handle multiple accounts in the same session](https://gitlab.com/honeyryderchuck/rodauth-select-account).
|
34
|
+
|
35
|
+
* Refresh Tokens are now expirable. The refresh token expiration period is governed by the `oauth_refresh_token_expires_in` option (default: 1 year), and is the period for which a refresh token can be used after its respective access token expired.
|
36
|
+
|
37
|
+
#### Bugfixes
|
38
|
+
|
39
|
+
* Default Templates now being packaged, as a way to provide a default experience to the OAuth journeys.
|
40
|
+
|
41
|
+
* fixing metadata urls when plugin loaded with a prefix path (@ianks)
|
42
|
+
|
43
|
+
* All date/time-based calculations, such as determining an expiration date, or checking if a token has expired, are now performed using database arithmetic operations, using sequel's `date_arithmetic` plugin. This will eliminate subtle bugs, such as when the database timezone is different than the application OS timezone.
|
44
|
+
|
45
|
+
* OIDC configuration endpoint is now stricter, eliminating JSON metadata inherited from the Oauth metadata endpoint. (@ianks)
|
46
|
+
|
47
|
+
#### Chore
|
48
|
+
|
49
|
+
Use `rodauth.convert_timestamp` in the templates, whenever dates are displayed.
|
50
|
+
|
51
|
+
Set HTTP Cache headers for metadata responses, such as `/.well-known/oauth-authorization-server` and `/.well-known/openid-configuration`, so they can be stored at the edge. The cache will be valid for 1 day (this value isn't set by an option yet).
|
52
|
+
|
53
|
+
### 0.2.0
|
54
|
+
|
55
|
+
#### Features
|
56
|
+
|
57
|
+
##### SAML Assertion Grant Type
|
58
|
+
|
59
|
+
`rodauth-auth` now supports using a SAML Assertion to request for an Access token.In order to enable, you have to:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
plugin :rodauth do
|
63
|
+
enable :oauth_saml
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
For more info about integrating it, [check the wiki](https://gitlab.com/honeyryderchuck/rodauth-oauth/-/wikis/SAML-Assertion-Access-Tokens).
|
68
|
+
|
69
|
+
##### Supporting rotating keys
|
70
|
+
|
71
|
+
At some point, you'll want to replace the pkeys and algorithm used to generate and verify the JWT access tokens, but you want to keep validating previously-distributed JWT tokens, at least until they expire. Now you can, via two new options, `oauth_jwt_legacy_public_key` and `oauth_jwt_legacy_algorithm`, which will be declared in the JWKs URI and used to verify access tokens.
|
72
|
+
|
73
|
+
|
74
|
+
##### Reuse access tokens
|
75
|
+
|
76
|
+
If the `oauth_reuse_access_token` is set, if there's already an existing valid access token, any new grant for the same application / account / scope will keep the same access token. This can be helpful in scenarios where one wants the same access token distributed across devices.
|
77
|
+
|
78
|
+
##### require_authorizable_account
|
79
|
+
|
80
|
+
The method used to verify access to the authorize flow is called `require_authorizable_account`. By default, it checks if a user is logged in by using rodauth's own `require_account`. This is the method you'd want to redefine in order to augment these requirements, i.e. request 2fa authentication.
|
81
|
+
|
82
|
+
#### Improvements
|
83
|
+
|
84
|
+
Expired and revoked access tokens end up generating a lot of garbage, which will have to be periodically cleaned up. You can mitigate this now by setting a uniqueness index for a group of columns, i.e. if you set a uniqueness index for the `oauth_application_id/account_id/scopes` column, `rodauth-oauth` will transparently reuse the same db entry to store the new access token. If setting some other type of uniqueness index, make sure to update the option `oauth_tokens_unique_columns` (the array of columns from the uniqueness index).
|
85
|
+
|
86
|
+
#### Bugfixes
|
87
|
+
|
88
|
+
Calling `before_*_route` callbacks appropriately.
|
89
|
+
|
90
|
+
Fixed some mishandling of HTTP headers when in in resource-server mode.
|
91
|
+
|
92
|
+
#### Chore
|
93
|
+
|
94
|
+
* 97.7% test coverage;
|
95
|
+
* `rodauth-oauth` CI tests run against sqlite, postgresql and mysql.
|
96
|
+
|
97
|
+
### 0.1.0
|
98
|
+
|
99
|
+
(31/7/2020)
|
100
|
+
|
101
|
+
#### Features
|
102
|
+
|
103
|
+
##### OpenID
|
104
|
+
|
105
|
+
`rodauth-oauth` now ships with support for [OpenID Connect](https://openid.net/connect/). In order to enable, you have to:
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
plugin :rodauth do
|
109
|
+
enable :oidc
|
110
|
+
end
|
111
|
+
```
|
112
|
+
|
113
|
+
For more info about integrating it, [check the wiki](https://gitlab.com/honeyryderchuck/rodauth-oauth/-/wikis/home#openid-connect-since-v01).
|
114
|
+
|
115
|
+
It supports omniauth openID integrations out-of-the-box, [check the OpenID example, which integrates with omniauth_openid_connect](https://gitlab.com/honeyryderchuck/rodauth-oauth/-/tree/master/examples).
|
116
|
+
|
117
|
+
#### Improvements
|
118
|
+
|
119
|
+
* JWT: `sub` claim now also handles "pairwise" subjects. For that, you have to set the `oauth_jwt_subject_type` option (`"public"` or `"pairwise"`) and `oauth_jwt_subject_secret` (will be used for salting the `sub` when the type is `"pairwise"`).
|
120
|
+
* JWT: `auth_time` claim is now supported; if your application uses the `rodauth` feature `:account_expiration`, it'll use the `last_account_login_at` method, otherwise you can set the `last_account_login_at` option:
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
last_account_login_at do
|
124
|
+
convert_timestamp(db[accounts_table].where(account_id_column => account_id).get(:that_column_where_you_keep_the_data))
|
125
|
+
end
|
126
|
+
```
|
127
|
+
* JWT: `iss` claim now defaults to `authorization_server_url` when not defined;
|
128
|
+
* JWT: `aud` claim now defaults to the token application's client ID (`client_id` claim was removed as a result);
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
#### Breaking Changes
|
133
|
+
|
134
|
+
`rodauth-oauth` URLs no longer have the `oauth-` prefix, so make sure you update your integrations accordingly, i.e. where you used to rely on `/oauth-authorize`, you'll have to use `/authorize`.
|
135
|
+
|
136
|
+
URI schemes for client applications redirect URIs have to be `https`. In order to override this, set the `oauth_valid_uri_schemes` to an array of your expected URI schemes.
|
137
|
+
|
138
|
+
|
139
|
+
#### Bugfixes
|
140
|
+
|
141
|
+
* Authorization request submission can receive the `scope` as an array of values now, instead of only dealing with receiving a white-space separated list.
|
142
|
+
* fixed trailing "/" in the "issuer" value in server metadata (`https://server.com/` -> `https://server.com`).
|
143
|
+
|
144
|
+
|
145
|
+
### 0.0.6
|
146
|
+
|
147
|
+
(6/7/2020)
|
148
|
+
|
149
|
+
#### Features
|
150
|
+
|
151
|
+
The `oauth_jwt` feature now supports JWT Secured Authorization Request (JAR) (see https://tools.ietf.org/html/draft-ietf-oauth-jwsreq-20). This means that client applications can send the authorization parameters inside a signed JWT. The client applications keeps the private key, while the authorization server **must** store a public key for the client application. For encrypted JWTs, the client application should use one of the public encryption keys exposed in the JWKs URI, to encrypt the JWT. Remember, **tokens must be signed then encrypted** (or just signed).
|
152
|
+
|
153
|
+
###### Options:
|
154
|
+
|
155
|
+
* `:oauth_application_jws_jwk_column`: db column where the public key is stored; since it's stored in the JWS format, it can be stored either as a String (JSON-encoded), or as an hstore (if you're using postgresql);
|
156
|
+
* `:oauth_jwt_jwe_key`: key used to decrypt the request JWT;
|
157
|
+
* `:oauth_jwt_jwe_public_key`: key used to encrypt the request JWT, and which will be exposed in the JWKs URI in the JWK format;
|
158
|
+
|
159
|
+
|
160
|
+
#### Improvements
|
161
|
+
|
162
|
+
* Removing all `_param` options; these defined the URL params, however we're using protocol-defined params, so it's unlikely (and undesired) that these'll change.
|
163
|
+
* Hitting the revoke endpoint with a JWT access token returns a 400 error;
|
164
|
+
|
165
|
+
#### Chore
|
166
|
+
|
167
|
+
Removed React Javascript from example applications.
|
168
|
+
|
169
|
+
|
170
|
+
### 0.0.5
|
171
|
+
|
172
|
+
(26/6/2020)
|
6
173
|
|
7
174
|
#### Features
|
8
175
|
|
@@ -39,7 +206,9 @@ It **requires** the authorization to implement the server metadata endpoint (`/.
|
|
39
206
|
* option `scopes_param` renamed to `scope_param`;
|
40
207
|
*
|
41
208
|
|
42
|
-
## 0.0.4
|
209
|
+
## 0.0.4
|
210
|
+
|
211
|
+
(13/6/2020)
|
43
212
|
|
44
213
|
### Features
|
45
214
|
|
@@ -76,7 +245,9 @@ The `oauth_jwt` feature now allows the usage of access tokens to authorize the g
|
|
76
245
|
|
77
246
|
* Fixed scope claim of JWT ("scopes" -> "scope");
|
78
247
|
|
79
|
-
## 0.0.3
|
248
|
+
## 0.0.3
|
249
|
+
|
250
|
+
(5/6/2020)
|
80
251
|
|
81
252
|
### Features
|
82
253
|
|
@@ -108,7 +279,9 @@ end
|
|
108
279
|
* renamed the existing `use_oauth_implicit_grant_type` to `use_oauth_implicit_grant_type?`;
|
109
280
|
* It's now usable as JSON API (small caveat: POST authorize will still redirect on success...);
|
110
281
|
|
111
|
-
## 0.0.2
|
282
|
+
## 0.0.2
|
283
|
+
|
284
|
+
(29/5/2020)
|
112
285
|
|
113
286
|
### Features
|
114
287
|
|
@@ -124,6 +297,8 @@ end
|
|
124
297
|
|
125
298
|
* usage of client secret for authorizing the generation of tokens, as the spec mandates (and refraining from them when doing PKCE).
|
126
299
|
|
127
|
-
## 0.0.1
|
300
|
+
## 0.0.1
|
301
|
+
|
302
|
+
(14/5/2020)
|
128
303
|
|
129
304
|
Initial implementation of the Oauth 2.0 framework, with an example app done using roda.
|
data/README.md
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# Rodauth::Oauth
|
2
2
|
|
3
|
-
[](https://gitlab.com/honeyryderchuck/rodauth-oauth/-/
|
4
|
-
[](https://gitlab.
|
3
|
+
[](https://gitlab.com/honeyryderchuck/rodauth-oauth/-/pipelines?page=1&ref=master)
|
4
|
+
[](https://honeyryderchuck.gitlab.io/rodauth-oauth/coverage/#_AllFiles)
|
5
5
|
|
6
6
|
This is an extension to the `rodauth` gem which implements the [OAuth 2.0 framework](https://tools.ietf.org/html/rfc6749) for an authorization server.
|
7
7
|
|
8
8
|
## Features
|
9
9
|
|
10
|
-
This gem implements:
|
10
|
+
This gem implements the following RFCs and features of OAuth:
|
11
11
|
|
12
12
|
* [The OAuth 2.0 protocol framework](https://tools.ietf.org/html/rfc6749):
|
13
13
|
* [Authorization grant flow](https://tools.ietf.org/html/rfc6749#section-1.3);
|
@@ -21,8 +21,12 @@ This gem implements:
|
|
21
21
|
* Access Type (Token refresh online and offline);
|
22
22
|
* [MAC Authentication Scheme](https://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-02);
|
23
23
|
* [JWT Acess Tokens](https://tools.ietf.org/html/draft-ietf-oauth-access-token-jwt-07);
|
24
|
+
* [SAML 2.0 Assertion Access Tokens](https://tools.ietf.org/html/draft-ietf-oauth-saml2-bearer-03);
|
25
|
+
* [JWT Secured Authorization Requests](https://tools.ietf.org/html/draft-ietf-oauth-jwsreq-20);
|
24
26
|
* OAuth application and token management dashboards;
|
25
27
|
|
28
|
+
It also implements the [OpenID Connect layer](https://openid.net/connect/) on top of the OAuth features it provides.
|
29
|
+
|
26
30
|
This gem supports also rails (through [rodauth-rails]((https://github.com/janko/rodauth-rails))).
|
27
31
|
|
28
32
|
|
@@ -42,6 +46,15 @@ Or install it yourself as:
|
|
42
46
|
|
43
47
|
$ gem install rodauth-oauth
|
44
48
|
|
49
|
+
|
50
|
+
## Resources
|
51
|
+
| | |
|
52
|
+
| ------------- | ----------------------------------------------------------- |
|
53
|
+
| Website | https://honeyryderchuck.gitlab.io/rodauth-oauth/ |
|
54
|
+
| Documentation | https://honeyryderchuck.gitlab.io/rodauth-oauth/rdoc/ |
|
55
|
+
| Wiki | https://gitlab.com/honeyryderchuck/rodauth-oauth/wikis/home |
|
56
|
+
| CI | https://gitlab.com/honeyryderchuck/rodauth-oauth/pipelines |
|
57
|
+
|
45
58
|
## Usage
|
46
59
|
|
47
60
|
This tutorial assumes you already read the documentation and know how to set up `rodauth`. After that, integrating `roda-auth` will look like:
|
@@ -85,11 +98,22 @@ route do |r|
|
|
85
98
|
end
|
86
99
|
```
|
87
100
|
|
88
|
-
|
101
|
+
|
102
|
+
For OpenID, it's very similar to the example above:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
plugin :rodauth do
|
106
|
+
# enable it in the plugin
|
107
|
+
enable :login, :openid
|
108
|
+
oauth_application_default_scope %w[openid]
|
109
|
+
oauth_application_scopes %w[openid email profile]
|
110
|
+
end
|
111
|
+
```
|
112
|
+
|
89
113
|
|
90
114
|
### Example (TL;DR)
|
91
115
|
|
92
|
-
If you're familiar with the technology and want to skip the next paragraphs, just [check our
|
116
|
+
If you're familiar with the technology and want to skip the next paragraphs, just [check our example applications](https://gitlab.com/honeyryderchuck/rodauth-oauth/-/tree/master/examples/).
|
93
117
|
|
94
118
|
|
95
119
|
Generating tokens happens mostly server-to-server, so here's an example using:
|
@@ -100,7 +124,7 @@ Generating tokens happens mostly server-to-server, so here's an example using:
|
|
100
124
|
|
101
125
|
```ruby
|
102
126
|
require "httpx"
|
103
|
-
response = HTTPX.post("https://auth_server/
|
127
|
+
response = HTTPX.post("https://auth_server/token",json: {
|
104
128
|
client_id: ENV["OAUTH_CLIENT_ID"],
|
105
129
|
client_secret: ENV["OAUTH_CLIENT_SECRET"],
|
106
130
|
grant_type: "authorization_code",
|
@@ -114,7 +138,7 @@ puts payload #=> {"access_token" => "awr23f3h8f9d2h89...", "refresh_token" => "2
|
|
114
138
|
##### cURL
|
115
139
|
|
116
140
|
```
|
117
|
-
> curl --data '{"client_id":"$OAUTH_CLIENT_ID","client_secret":"$OAUTH_CLIENT_SECRET","grant_type":"authorization_code","code":"oiweicnewdh32fhoi3hf3ihfo2ih3f2o3as"}' https://auth_server/
|
141
|
+
> curl --data '{"client_id":"$OAUTH_CLIENT_ID","client_secret":"$OAUTH_CLIENT_SECRET","grant_type":"authorization_code","code":"oiweicnewdh32fhoi3hf3ihfo2ih3f2o3as"}' https://auth_server/token
|
118
142
|
```
|
119
143
|
|
120
144
|
#### Refresh Token
|
@@ -125,7 +149,7 @@ Refreshing expired tokens also happens mostly server-to-server, here's an exampl
|
|
125
149
|
|
126
150
|
```ruby
|
127
151
|
require "httpx"
|
128
|
-
response = HTTPX.post("https://auth_server/
|
152
|
+
response = HTTPX.post("https://auth_server/token",json: {
|
129
153
|
client_id: ENV["OAUTH_CLIENT_ID"],
|
130
154
|
client_secret: ENV["OAUTH_CLIENT_SECRET"],
|
131
155
|
grant_type: "refresh_token",
|
@@ -139,7 +163,7 @@ puts payload #=> {"access_token" => "awr23f3h8f9d2h89...", "token_type" => "Bear
|
|
139
163
|
##### cURL
|
140
164
|
|
141
165
|
```
|
142
|
-
> curl -H "X-your-auth-scheme: $SERVER_KEY" --data '{"client_id":"$OAUTH_CLIENT_ID","client_secret":"$OAUTH_CLIENT_SECRET","grant_type":"token","token":"2r89hfef4j9f90d2j2390jf390g"}' https://auth_server/
|
166
|
+
> curl -H "X-your-auth-scheme: $SERVER_KEY" --data '{"client_id":"$OAUTH_CLIENT_ID","client_secret":"$OAUTH_CLIENT_SECRET","grant_type":"token","token":"2r89hfef4j9f90d2j2390jf390g"}' https://auth_server/token
|
143
167
|
```
|
144
168
|
|
145
169
|
#### Revoking tokens
|
@@ -150,7 +174,7 @@ Token revocation can be done both by the idenntity owner or the application owne
|
|
150
174
|
require "httpx"
|
151
175
|
httpx = HTTPX.plugin(:basic_authorization)
|
152
176
|
response = httpx.basic_authentication(ENV["CLIENT_ID"], ENV["CLIENT_SECRET"])
|
153
|
-
.post("https://auth_server/
|
177
|
+
.post("https://auth_server/revoke",json: {
|
154
178
|
token_type_hint: "access_token", # can also be "refresh:tokn"
|
155
179
|
token: "2r89hfef4j9f90d2j2390jf390g"
|
156
180
|
})
|
@@ -162,7 +186,7 @@ puts payload #=> {"access_token" => "awr23f3h8f9d2h89...", "token_type" => "Bear
|
|
162
186
|
##### cURL
|
163
187
|
|
164
188
|
```
|
165
|
-
> curl -H "X-your-auth-scheme: $SERVER_KEY" --data '{"client_id":"$OAUTH_CLIENT_ID","token_type_hint":"access_token","token":"2r89hfef4j9f90d2j2390jf390g"}' https://auth_server/
|
189
|
+
> curl -H "X-your-auth-scheme: $SERVER_KEY" --data '{"client_id":"$OAUTH_CLIENT_ID","token_type_hint":"access_token","token":"2r89hfef4j9f90d2j2390jf390g"}' https://auth_server/revoke
|
166
190
|
```
|
167
191
|
|
168
192
|
#### Token introspection
|
@@ -173,7 +197,7 @@ Token revocation can be used to determine the state of a token (whether active,
|
|
173
197
|
require "httpx"
|
174
198
|
httpx = HTTPX.plugin(:basic_authorization)
|
175
199
|
response = httpx.basic_authentication(ENV["CLIENT_ID"], ENV["CLIENT_SECRET"])
|
176
|
-
.post("https://auth_server/
|
200
|
+
.post("https://auth_server/introspect",json: {
|
177
201
|
token_type_hint: "access_token", # can also be "refresh:tokn"
|
178
202
|
token: "2r89hfef4j9f90d2j2390jf390g"
|
179
203
|
})
|
@@ -185,7 +209,7 @@ puts payload #=> {"active" => true, "scope" => "read write" ....
|
|
185
209
|
##### cURL
|
186
210
|
|
187
211
|
```
|
188
|
-
> curl -H "X-your-auth-scheme: $SERVER_KEY" --data '{"client_id":"$OAUTH_CLIENT_ID","token_type_hint":"access_token","token":"2r89hfef4j9f90d2j2390jf390g"}' https://auth_server/
|
212
|
+
> curl -H "X-your-auth-scheme: $SERVER_KEY" --data '{"client_id":"$OAUTH_CLIENT_ID","token_type_hint":"access_token","token":"2r89hfef4j9f90d2j2390jf390g"}' https://auth_server/revoke
|
189
213
|
```
|
190
214
|
|
191
215
|
### Authorization Server Metadata
|
@@ -242,10 +266,10 @@ The rodauth default setup expects the roda `render` plugin to be activated; by d
|
|
242
266
|
|
243
267
|
Once you set it up, by default, the following endpoints will be available:
|
244
268
|
|
245
|
-
* `GET /
|
246
|
-
* `POST /
|
247
|
-
* `POST /
|
248
|
-
* `POST /
|
269
|
+
* `GET /authorize`: Loads the OAuth authorization HTML form;
|
270
|
+
* `POST /authorize`: Responds to an OAuth authorization request, as [per the spec](https://tools.ietf.org/html/rfc6749#section-4);
|
271
|
+
* `POST /token`: Generates OAuth tokens as [per the spec](https://tools.ietf.org/html/rfc6749#section-4.4.2);
|
272
|
+
* `POST /revoke`: Revokes OAuth tokens as [per the spec](https://tools.ietf.org/html/rfc7009);
|
249
273
|
|
250
274
|
### OAuth applications
|
251
275
|
|
@@ -425,7 +449,7 @@ The "Proof Key for Code Exchange by OAuth Public Clients" (aka PKCE) flow, which
|
|
425
449
|
```ruby
|
426
450
|
# with httpx
|
427
451
|
require "httpx"
|
428
|
-
response = HTTPX.post("https://auth_server/
|
452
|
+
response = HTTPX.post("https://auth_server/token",json: {
|
429
453
|
client_id: ENV["OAUTH_CLIENT_ID"],
|
430
454
|
grant_type: "authorization_code",
|
431
455
|
code: "oiweicnewdh32fhoi3hf3ihfo2ih3f2o3as",
|
@@ -476,7 +500,7 @@ Generating an access token will deliver the following fields:
|
|
476
500
|
```ruby
|
477
501
|
# with httpx
|
478
502
|
require "httpx"
|
479
|
-
response = httpx.post("https://auth_server/
|
503
|
+
response = httpx.post("https://auth_server/token",json: {
|
480
504
|
client_id: env["oauth_client_id"],
|
481
505
|
client_secret: env["oauth_client_secret"],
|
482
506
|
grant_type: "authorization_code",
|
@@ -575,7 +599,7 @@ which adds an extra layer of protection.
|
|
575
599
|
|
576
600
|
#### JWKS URI
|
577
601
|
|
578
|
-
A route is defined for getting the JWK Set in a JSON format; this is typically used by client applications, who need the JWK set to decode the JWT token. This URL is typically `https://oauth-server/
|
602
|
+
A route is defined for getting the JWK Set in a JSON format; this is typically used by client applications, who need the JWK set to decode the JWT token. This URL is typically `https://oauth-server/jwks`.
|
579
603
|
|
580
604
|
#### JWT Bearer as authorization grant
|
581
605
|
|
@@ -584,7 +608,7 @@ One can emit a new access token by using the bearer access token as grant. This
|
|
584
608
|
```ruby
|
585
609
|
# with httpx
|
586
610
|
require "httpx"
|
587
|
-
response = httpx.post("https://auth_server/
|
611
|
+
response = httpx.post("https://auth_server/token",json: {
|
588
612
|
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
|
589
613
|
assertion: "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOjEsImlzcyI6IkV4YW1wbGUiLCJpYXQiOjE1OTIwMDk1MDEsImNsaWVudF9pZCI6IkNMSUVOVF9JRCIsImV4cCI6MTU5MjAxMzEwMSwiYXVkIjpudWxsLCJzY29wZSI6InVzZXIucmVhZCB1c2VyLndyaXRlIiwianRpIjoiOGM1NTVjMjdiOWRjNDdmOTcyNWRkYzBhMjk0NzA1ZTA4NzFkY2JlN2Q5ZTNlMmVkNGE1ZTBiOGZlNTZlYzcxMSJ9.AlxKRtE3ec0mtyBSDx4VseND4eC6cH5ubtv8gfYxxsc"
|
590
614
|
})
|
@@ -29,7 +29,8 @@ class CreateRodauthOAuth < ActiveRecord::Migration<%= migration_version %>
|
|
29
29
|
# uncomment to enable PKCE
|
30
30
|
# t.string :code_challenge
|
31
31
|
# t.string :code_challenge_method
|
32
|
-
|
32
|
+
# uncomment to use OIDC nonce
|
33
|
+
# t.string :nonce
|
33
34
|
t.index(%i[oauth_application_id code], unique: true)
|
34
35
|
end
|
35
36
|
|
@@ -42,18 +43,20 @@ class CreateRodauthOAuth < ActiveRecord::Migration<%= migration_version %>
|
|
42
43
|
t.foreign_key :oauth_tokens, column: :oauth_token_id
|
43
44
|
t.integer :oauth_application_id
|
44
45
|
t.foreign_key :oauth_applications, column: :oauth_application_id
|
45
|
-
t.string :token, null: false, token: true
|
46
|
+
t.string :token, null: false, token: true, unique: true
|
46
47
|
# uncomment if setting oauth_tokens_token_hash_column
|
47
48
|
# and delete the token column
|
48
|
-
# t.string :token_hash, token: true
|
49
|
-
t.string :refresh_token
|
49
|
+
# t.string :token_hash, token: true, unique: true
|
50
|
+
t.string :refresh_token, unique: true
|
50
51
|
# uncomment if setting oauth_tokens_refresh_token_hash_column
|
51
52
|
# and delete the refresh_token column
|
52
|
-
# t.string :refresh_token_hash, token: true
|
53
|
+
# t.string :refresh_token_hash, token: true, unique: true
|
53
54
|
t.datetime :expires_in, null: false
|
54
55
|
t.datetime :revoked_at
|
55
56
|
t.string :scopes, null: false
|
56
57
|
t.datetime :created_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
|
58
|
+
# uncomment to use OIDC nonce
|
59
|
+
# t.string :nonce
|
57
60
|
end
|
58
61
|
end
|
59
62
|
end
|