himari 0.6.0 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dcb5e4f61b85b69f1ec9b36205664930ab488c46d4bc1f0800a3481926092d2b
4
- data.tar.gz: eacc822fbf0ccb630a42dae0e7c130122980da8875480132047d23378e88b83a
3
+ metadata.gz: f986e727b538f1f6f512f6787e7546e1ebdaa942398053966d52db1383135fc8
4
+ data.tar.gz: a300ee5b77dc2e1f7c5befbae719876cc60f08a742d97c43f71bdd44fb170adc
5
5
  SHA512:
6
- metadata.gz: 125693e2f92b453fffd5bf5d1f0b34bce0e5f29e2c86ac8e6b068ce3d223d4ee4abda646c99165653a01bc2304d496ac7a26779553659afca7501acef247fc05
7
- data.tar.gz: 1227491aa891bbaa40c3db1c144bf2ceb429941206cf859f799f409623854c4a099613883579739b1c6ff6f7ee1fef47038063b1f8dc3f313e477a10f8a71ba9
6
+ metadata.gz: 1bf93eaa1f6f98c45ec2649278ccb571f26a530f7b5b4d6c35d0b15e250861f9fc7e6efdb7f3c77de9abd177330b86970d9b1de29df2a0cdb4c4d65f33933fb0
7
+ data.tar.gz: 033b8dfa409cea02e7ddd73a6369c261e0d79402ab7a82cab49cbffafc654b12bb08dabd42b824382d4143b426d2749117014b94e96bd4d1b67de7e2ca8e37ef
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [0.7.0] - 2026-06-06
2
+
3
+ ### Enhancements
4
+
5
+ - Authorization Server Issuer Identification (RFC 9207): the authorization endpoint now returns the `iss` parameter in all authorization responses (success and redirected errors), and discovery metadata advertises `authorization_response_iss_parameter_supported`
6
+
1
7
  ## [0.6.0] - 2026-06-03
2
8
 
3
9
  ### Enhancements
data/lib/himari/app.rb CHANGED
@@ -200,6 +200,7 @@ module Himari
200
200
  authz: authz,
201
201
  client: client,
202
202
  storage: config.storage,
203
+ issuer: config.issuer,
203
204
  consent: consent,
204
205
  logger: logger,
205
206
  ).call(env)
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rack/oauth2'
4
+
5
+ module Himari
6
+ # RFC 9207 Authorization Server Issuer Identification, implemented as extensions to rack-oauth2.
7
+ #
8
+ # rack-oauth2 builds the grant redirect from the response object handed to the authorization
9
+ # endpoint block, but constructs and finishes error redirects internally (Authorize#_call rescues
10
+ # and calls e.finish), so those error objects are out of reach. Instead we teach rack-oauth2 to
11
+ # carry an `iss` through both: the issuer is set on the request/response, and the response classes
12
+ # merge it into their protocol_params (the parameters rack-oauth2 places on the redirect). Errors
13
+ # copy it from the request the same way they copy state/redirect_uri.
14
+ module RackOAuth2Ext
15
+ # Carried by the grant response; always emitted because the grant is always a redirect.
16
+ # Prepended onto the base response so every response type (Code::Response calls super) gains the
17
+ # `iss` accessor, including the response objects the loaded extensions hand to the endpoint block.
18
+ module IssuerParam
19
+ attr_accessor :iss
20
+
21
+ def protocol_params
22
+ super.merge(iss:)
23
+ end
24
+ end
25
+
26
+ # Carried by error responses, but only emitted when the error is actually delivered to the
27
+ # client via redirect. RFC 9207 covers authorization responses, not the JSON error bodies
28
+ # rack-oauth2 returns directly to the user agent when there is no trusted redirect_uri.
29
+ module ErrorIssuerParam
30
+ attr_accessor :iss
31
+
32
+ def protocol_params
33
+ redirect? ? super.merge(iss:) : super
34
+ end
35
+ end
36
+
37
+ # rack-oauth2 stamps state and redirect_uri from the request onto every error it raises; thread
38
+ # the issuer along the same path so ErrorIssuerParam has a value to emit.
39
+ module RequestIssuer
40
+ attr_accessor :iss
41
+
42
+ private def error!(klass, error, description, options)
43
+ super
44
+ rescue Rack::OAuth2::Server::Abstract::Error => e
45
+ e.iss = iss if e.respond_to?(:iss=)
46
+ raise e
47
+ end
48
+ end
49
+
50
+ Rack::OAuth2::Server::Authorize::Response.prepend(IssuerParam)
51
+ Rack::OAuth2::Server::Authorize::Request.prepend(RequestIssuer)
52
+ [
53
+ Rack::OAuth2::Server::Authorize::BadRequest,
54
+ Rack::OAuth2::Server::Authorize::ServerError,
55
+ Rack::OAuth2::Server::Authorize::TemporarilyUnavailable,
56
+ ].each { |klass| klass.prepend(ErrorIssuerParam) }
57
+ end
58
+ end
@@ -4,6 +4,8 @@ require 'rack/oauth2'
4
4
  require 'digest/sha2'
5
5
  require 'openid_connect'
6
6
 
7
+ require 'himari/rack_oauth2_ext'
8
+
7
9
  module Himari
8
10
  module Services
9
11
  class OidcAuthorizationEndpoint
@@ -26,12 +28,14 @@ module Himari
26
28
  # @param authz [Himari::AuthorizationCode] pending (unpersisted) authz data
27
29
  # @param client [Himari::ClientRegistration]
28
30
  # @param storage [Himari::Storages::Base]
31
+ # @param issuer [String] issuer identifier, returned to the client as the RFC 9207 `iss` parameter
29
32
  # @param consent [:approve, :deny, nil] the user's consent decision (nil = not yet asked)
30
33
  # @param logger [Logger]
31
- def initialize(authz:, client:, storage:, consent: nil, logger: nil)
34
+ def initialize(authz:, client:, storage:, issuer:, consent: nil, logger: nil)
32
35
  @authz = authz
33
36
  @client = client
34
37
  @storage = storage
38
+ @issuer = issuer
35
39
  @consent = consent
36
40
  @logger = logger
37
41
  end
@@ -47,6 +51,11 @@ module Himari
47
51
 
48
52
  def app(env)
49
53
  Rack::OAuth2::Server::Authorize.new do |req, res|
54
+ # RFC 9207: hand the issuer to rack-oauth2 so both the grant response and any error it
55
+ # redirects back to the client carry the `iss` parameter (see Himari::RackOAuth2Ext).
56
+ req.iss = @issuer
57
+ res.iss = @issuer
58
+
50
59
  # sanity check
51
60
  unless @client.id == req.client_id
52
61
  @logger&.warn(Himari::LogLine.new('OidcAuthorizationEndpoint: @client.id != req.client_id', req: env['himari.request_as_log'], known_client: @client.id, given_client: req.client_id))
@@ -60,6 +60,7 @@ module Himari
60
60
  subject_types_supported: ['public'],
61
61
  id_token_signing_alg_values_supported: signing_keys.map(&:alg).uniq.sort,
62
62
  claims_supported: (DEFAULT_CLAIMS_SUPPORTED + @claims_supported).uniq,
63
+ authorization_response_iss_parameter_supported: true, # RFC 9207
63
64
  }.compact
64
65
  end
65
66
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Himari
4
- VERSION = "0.6.0"
4
+ VERSION = "0.7.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: himari
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sorah Fukumori
@@ -160,6 +160,7 @@ files:
160
160
  - lib/himari/middlewares/metadata_clients.rb
161
161
  - lib/himari/middlewares/signing_key.rb
162
162
  - lib/himari/provider_chain.rb
163
+ - lib/himari/rack_oauth2_ext.rb
163
164
  - lib/himari/refresh_token.rb
164
165
  - lib/himari/rule.rb
165
166
  - lib/himari/rule_processor.rb