Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .rubocop_gradual.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"lib/oauth2.rb:2435263975": [
[73, 11, 7, "ThreadSafety/ClassInstanceVariable: Avoid class instance variables.", 651502127]
],
"lib/oauth2/access_token.rb:558937598": [
"lib/oauth2/access_token.rb:1775225572": [
[64, 13, 5, "Style/IdenticalConditionalBranches: Move `t_key` out of the conditional.", 183811513],
[70, 13, 5, "Style/IdenticalConditionalBranches: Move `t_key` out of the conditional.", 183811513]
],
Expand Down
11 changes: 9 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
# Changelog
All notable changes to this project will be documented in this file.

The format (since v2) is based on [Keep a Changelog v1](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning v2](https://semver.org/spec/v2.0.0.html).
The format (since v2) is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- improved documentation by @pboling
- documentation notes in code comments and README highlighting OAuth 2.1 differences, with references, such as:
- PKCE required for auth code,
- exact redirect URI match,
- implicit/password grants omitted,
- avoid bearer tokens in query,
- refresh token guidance for public clients,
- simplified client definitions)
### Changed
### Deprecated
### Removed
Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,22 @@ Response instance will contain the `OAuth2::Error` instance.

### Authorization Grants

Note on OAuth 2.1 (draft):
- PKCE is required for all OAuth clients using the authorization code flow (especially public clients). Implement PKCE in your app when required by your provider. See RFC 7636 and RFC 8252.
- Redirect URIs must be compared using exact string matching by the Authorization Server.
- The Implicit grant (response_type=token) and the Resource Owner Password Credentials grant are omitted from OAuth 2.1; they remain here for OAuth 2.0 compatibility but should be avoided for new apps.
- Bearer tokens in the query string are omitted due to security risks; prefer Authorization header usage.
- Refresh tokens for public clients must either be sender-constrained (e.g., DPoP/MTLS) or one-time use.
- The definitions of public and confidential clients are simplified to refer only to whether the client has credentials.

References:
- OAuth 2.1 draft: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13
- Aaron Parecki: https://aaronparecki.com/2019/12/12/21/its-time-for-oauth-2-dot-1
- FusionAuth: https://fusionauth.io/blog/2020/04/15/whats-new-in-oauth-2-1
- Okta: https://developer.okta.com/blog/2019/12/13/oauth-2-1-how-many-rfcs
- Video: https://www.youtube.com/watch?v=g_aVPdwBTfw
- Differences overview: https://fusionauth.io/learn/expert-advice/oauth/differences-between-oauth-2-oauth-2-1/

Currently, the Authorization Code, Implicit, Resource Owner Password Credentials, Client Credentials, and Assertion
authentication grant types have helper strategy classes that simplify client
use. They are available via the [`#auth_code`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/auth_code.rb),
Expand Down
2 changes: 1 addition & 1 deletion docs/OAuth2.html
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ <h3 class="signature first" id="configure-class_method">
</div>

<div id="footer">
Generated on Sat Aug 30 20:09:59 2025 by
Generated on Sun Aug 31 03:36:08 2025 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.37 (ruby-3.4.5).
</div>
Expand Down
2 changes: 1 addition & 1 deletion docs/OAuth2/AccessToken.html
Original file line number Diff line number Diff line change
Expand Up @@ -3069,7 +3069,7 @@ <h3 class="signature " id="to_hash-instance_method">
</div>

<div id="footer">
Generated on Sat Aug 30 20:09:59 2025 by
Generated on Sun Aug 31 03:36:08 2025 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.37 (ruby-3.4.5).
</div>
Expand Down
2 changes: 1 addition & 1 deletion docs/OAuth2/Authenticator.html
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,7 @@ <h3 class="signature first" id="apply-instance_method">
</div>

<div id="footer">
Generated on Sat Aug 30 20:09:59 2025 by
Generated on Sun Aug 31 03:36:08 2025 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.37 (ruby-3.4.5).
</div>
Expand Down
19 changes: 12 additions & 7 deletions docs/OAuth2/Client.html
Original file line number Diff line number Diff line change
Expand Up @@ -1843,6 +1843,9 @@ <h3 class="signature " id="redirection_params-instance_method">
requesting authorization. If it is provided at authorization time it MUST<br />
also be provided with the token exchange request.</p>

<p>OAuth 2.1 note: Authorization Servers must compare redirect URIs using exact string matching.<br />
This client simply forwards the configured redirect_uri; the exact-match validation happens server-side.</p>

<p>Providing :redirect_uri to the OAuth2::Client instantiation will take<br />
care of managing this.</p>

Expand Down Expand Up @@ -1880,6 +1883,8 @@ <h3 class="signature " id="redirection_params-instance_method">

<li><a href="https://datatracker.ietf.org/doc/html/rfc6749#section-10.6" target="_parent" title="https://datatracker.ietf.org/doc/html/rfc6749#section-10.6">https://datatracker.ietf.org/doc/html/rfc6749#section-10.6</a></li>

<li><a href="https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13" target="_parent" title="https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13">https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13</a></li>

</ul>

</div><table class="source_code">
Expand All @@ -1888,16 +1893,16 @@ <h3 class="signature " id="redirection_params-instance_method">
<pre class="lines">


335
336
337
338
339
340
341</pre>
341
342
343
344
345</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/oauth2/client.rb', line 335</span>
<pre class="code"><span class="info file"># File 'lib/oauth2/client.rb', line 339</span>

<span class='kw'>def</span> <span class='id identifier rubyid_redirection_params'>redirection_params</span>
<span class='kw'>if</span> <span class='id identifier rubyid_options'>options</span><span class='lbracket'>[</span><span class='symbol'>:redirect_uri</span><span class='rbracket'>]</span>
Expand Down Expand Up @@ -2651,7 +2656,7 @@ <h3 class="signature " id="token_url-instance_method">
</div>

<div id="footer">
Generated on Sat Aug 30 20:09:59 2025 by
Generated on Sun Aug 31 03:36:08 2025 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.37 (ruby-3.4.5).
</div>
Expand Down
2 changes: 1 addition & 1 deletion docs/OAuth2/Error.html
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ <h3 class="signature " id="response-instance_method">
</div>

<div id="footer">
Generated on Sat Aug 30 20:09:59 2025 by
Generated on Sun Aug 31 03:36:08 2025 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.37 (ruby-3.4.5).
</div>
Expand Down
2 changes: 1 addition & 1 deletion docs/OAuth2/FilteredAttributes.html
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ <h3 class="signature first" id="inspect-instance_method">
</div>

<div id="footer">
Generated on Sat Aug 30 20:09:59 2025 by
Generated on Sun Aug 31 03:36:08 2025 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.37 (ruby-3.4.5).
</div>
Expand Down
2 changes: 1 addition & 1 deletion docs/OAuth2/FilteredAttributes/ClassMethods.html
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ <h3 class="signature " id="filtered_attributes-instance_method">
</div>

<div id="footer">
Generated on Sat Aug 30 20:09:59 2025 by
Generated on Sun Aug 31 03:36:08 2025 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.37 (ruby-3.4.5).
</div>
Expand Down
2 changes: 1 addition & 1 deletion docs/OAuth2/Response.html
Original file line number Diff line number Diff line change
Expand Up @@ -1619,7 +1619,7 @@ <h3 class="signature " id="status-instance_method">
</div>

<div id="footer">
Generated on Sat Aug 30 20:09:59 2025 by
Generated on Sun Aug 31 03:36:08 2025 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.37 (ruby-3.4.5).
</div>
Expand Down
2 changes: 1 addition & 1 deletion docs/OAuth2/Strategy.html
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ <h2>Defined Under Namespace</h2>
</div>

<div id="footer">
Generated on Sat Aug 30 20:09:59 2025 by
Generated on Sun Aug 31 03:36:08 2025 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.37 (ruby-3.4.5).
</div>
Expand Down
2 changes: 1 addition & 1 deletion docs/OAuth2/Strategy/Assertion.html
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ <h3 class="signature " id="get_token-instance_method">
</div>

<div id="footer">
Generated on Sat Aug 30 20:09:59 2025 by
Generated on Sun Aug 31 03:36:08 2025 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.37 (ruby-3.4.5).
</div>
Expand Down
54 changes: 34 additions & 20 deletions docs/OAuth2/Strategy/AuthCode.html
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,20 @@ <h2>Overview</h2><div class="docstring">
<div class="discussion">
<p>The Authorization Code Strategy</p>

<p>OAuth 2.1 notes:</p>
<ul>
<li>PKCE is required for all OAuth clients using the authorization code flow (especially public clients).<br />
This library does not enforce PKCE generation/verification; implement PKCE in your application when required.</li>
<li>Redirect URIs must be compared using exact string matching by the Authorization Server.<br />
This client forwards redirect_uri but does not perform server-side validation.</li>
</ul>

<p>References:</p>
<ul>
<li>OAuth 2.1 draft: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13</li>
<li>OAuth for native apps (RFC 8252) and PKCE (RFC 7636)</li>
</ul>


</div>
</div>
Expand Down Expand Up @@ -274,12 +288,12 @@ <h3 class="signature first" id="authorize_params-instance_method">
<pre class="lines">


12
13
14</pre>
22
23
24</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/oauth2/strategy/auth_code.rb', line 12</span>
<pre class="code"><span class="info file"># File 'lib/oauth2/strategy/auth_code.rb', line 22</span>

<span class='kw'>def</span> <span class='id identifier rubyid_authorize_params'>authorize_params</span><span class='lparen'>(</span><span class='id identifier rubyid_params'>params</span> <span class='op'>=</span> <span class='lbrace'>{</span><span class='rbrace'>}</span><span class='rparen'>)</span>
<span class='id identifier rubyid_params'>params</span><span class='period'>.</span><span class='id identifier rubyid_merge'>merge</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>response_type</span><span class='tstring_end'>&quot;</span></span> <span class='op'>=&gt;</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>code</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>client_id</span><span class='tstring_end'>&quot;</span></span> <span class='op'>=&gt;</span> <span class='ivar'>@client</span><span class='period'>.</span><span class='id identifier rubyid_id'>id</span><span class='rparen'>)</span>
Expand Down Expand Up @@ -335,13 +349,13 @@ <h3 class="signature " id="authorize_url-instance_method">
<pre class="lines">


19
20
21
22</pre>
29
30
31
32</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/oauth2/strategy/auth_code.rb', line 19</span>
<pre class="code"><span class="info file"># File 'lib/oauth2/strategy/auth_code.rb', line 29</span>

<span class='kw'>def</span> <span class='id identifier rubyid_authorize_url'>authorize_url</span><span class='lparen'>(</span><span class='id identifier rubyid_params'>params</span> <span class='op'>=</span> <span class='lbrace'>{</span><span class='rbrace'>}</span><span class='rparen'>)</span>
<span class='id identifier rubyid_assert_valid_params'>assert_valid_params</span><span class='lparen'>(</span><span class='id identifier rubyid_params'>params</span><span class='rparen'>)</span>
Expand Down Expand Up @@ -437,18 +451,18 @@ <h3 class="signature " id="get_token-instance_method">
<pre class="lines">


30
31
32
33
34
35
36
37
38</pre>
40
41
42
43
44
45
46
47
48</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/oauth2/strategy/auth_code.rb', line 30</span>
<pre class="code"><span class="info file"># File 'lib/oauth2/strategy/auth_code.rb', line 40</span>

<span class='kw'>def</span> <span class='id identifier rubyid_get_token'>get_token</span><span class='lparen'>(</span><span class='id identifier rubyid_code'>code</span><span class='comma'>,</span> <span class='id identifier rubyid_params'>params</span> <span class='op'>=</span> <span class='lbrace'>{</span><span class='rbrace'>}</span><span class='comma'>,</span> <span class='id identifier rubyid_opts'>opts</span> <span class='op'>=</span> <span class='lbrace'>{</span><span class='rbrace'>}</span><span class='rparen'>)</span>
<span class='id identifier rubyid_params'>params</span> <span class='op'>=</span> <span class='lbrace'>{</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>grant_type</span><span class='tstring_end'>&quot;</span></span> <span class='op'>=&gt;</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>authorization_code</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>code</span><span class='tstring_end'>&quot;</span></span> <span class='op'>=&gt;</span> <span class='id identifier rubyid_code'>code</span><span class='rbrace'>}</span><span class='period'>.</span><span class='id identifier rubyid_merge'>merge</span><span class='lparen'>(</span><span class='ivar'>@client</span><span class='period'>.</span><span class='id identifier rubyid_redirection_params'>redirection_params</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_merge'>merge</span><span class='lparen'>(</span><span class='id identifier rubyid_params'>params</span><span class='rparen'>)</span>
Expand All @@ -469,7 +483,7 @@ <h3 class="signature " id="get_token-instance_method">
</div>

<div id="footer">
Generated on Sat Aug 30 20:09:59 2025 by
Generated on Sun Aug 31 03:36:08 2025 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.37 (ruby-3.4.5).
</div>
Expand Down
2 changes: 1 addition & 1 deletion docs/OAuth2/Strategy/Base.html
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ <h3 class="signature first" id="initialize-instance_method">
</div>

<div id="footer">
Generated on Sat Aug 30 20:09:59 2025 by
Generated on Sun Aug 31 03:36:08 2025 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.37 (ruby-3.4.5).
</div>
Expand Down
2 changes: 1 addition & 1 deletion docs/OAuth2/Strategy/ClientCredentials.html
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ <h3 class="signature " id="get_token-instance_method">
</div>

<div id="footer">
Generated on Sat Aug 30 20:10:00 2025 by
Generated on Sun Aug 31 03:36:08 2025 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.37 (ruby-3.4.5).
</div>
Expand Down
38 changes: 24 additions & 14 deletions docs/OAuth2/Strategy/Implicit.html
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@ <h2>Overview</h2><div class="docstring">
<div class="discussion">
<p>The Implicit Strategy</p>

<p>IMPORTANT (OAuth 2.1): The Implicit grant (response_type=token) is omitted from the OAuth 2.1 draft specification.<br />
It remains here for backward compatibility with OAuth 2.0 providers. Prefer the Authorization Code flow with PKCE.</p>

<p>References:</p>
<ul>
<li>OAuth 2.1 draft: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13</li>
<li>Why drop implicit: https://aaronparecki.com/2019/12/12/21/its-time-for-oauth-2-dot-1</li>
<li>Background: https://fusionauth.io/learn/expert-advice/oauth/differences-between-oauth-2-oauth-2-1/</li>
</ul>


</div>
</div>
Expand Down Expand Up @@ -274,12 +284,12 @@ <h3 class="signature first" id="authorize_params-instance_method">
<pre class="lines">


12
13
14</pre>
20
21
22</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/oauth2/strategy/implicit.rb', line 12</span>
<pre class="code"><span class="info file"># File 'lib/oauth2/strategy/implicit.rb', line 20</span>

<span class='kw'>def</span> <span class='id identifier rubyid_authorize_params'>authorize_params</span><span class='lparen'>(</span><span class='id identifier rubyid_params'>params</span> <span class='op'>=</span> <span class='lbrace'>{</span><span class='rbrace'>}</span><span class='rparen'>)</span>
<span class='id identifier rubyid_params'>params</span><span class='period'>.</span><span class='id identifier rubyid_merge'>merge</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>response_type</span><span class='tstring_end'>&quot;</span></span> <span class='op'>=&gt;</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>token</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>client_id</span><span class='tstring_end'>&quot;</span></span> <span class='op'>=&gt;</span> <span class='ivar'>@client</span><span class='period'>.</span><span class='id identifier rubyid_id'>id</span><span class='rparen'>)</span>
Expand Down Expand Up @@ -335,13 +345,13 @@ <h3 class="signature " id="authorize_url-instance_method">
<pre class="lines">


19
20
21
22</pre>
27
28
29
30</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/oauth2/strategy/implicit.rb', line 19</span>
<pre class="code"><span class="info file"># File 'lib/oauth2/strategy/implicit.rb', line 27</span>

<span class='kw'>def</span> <span class='id identifier rubyid_authorize_url'>authorize_url</span><span class='lparen'>(</span><span class='id identifier rubyid_params'>params</span> <span class='op'>=</span> <span class='lbrace'>{</span><span class='rbrace'>}</span><span class='rparen'>)</span>
<span class='id identifier rubyid_assert_valid_params'>assert_valid_params</span><span class='lparen'>(</span><span class='id identifier rubyid_params'>params</span><span class='rparen'>)</span>
Expand Down Expand Up @@ -390,12 +400,12 @@ <h3 class="signature " id="get_token-instance_method">
<pre class="lines">


27
28
29</pre>
35
36
37</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/oauth2/strategy/implicit.rb', line 27</span>
<pre class="code"><span class="info file"># File 'lib/oauth2/strategy/implicit.rb', line 35</span>

<span class='kw'>def</span> <span class='id identifier rubyid_get_token'>get_token</span><span class='lparen'>(</span><span class='op'>*</span><span class='rparen'>)</span>
<span class='id identifier rubyid_raise'>raise</span><span class='lparen'>(</span><span class='const'>NotImplementedError</span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>The token is accessed differently in this strategy</span><span class='tstring_end'>&quot;</span></span><span class='rparen'>)</span>
Expand All @@ -410,7 +420,7 @@ <h3 class="signature " id="get_token-instance_method">
</div>

<div id="footer">
Generated on Sat Aug 30 20:09:59 2025 by
Generated on Sun Aug 31 03:36:08 2025 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.37 (ruby-3.4.5).
</div>
Expand Down
Loading
Loading