Class: Identizer::TokenMinter
- Inherits:
-
Object
- Object
- Identizer::TokenMinter
- Defined in:
- lib/identizer/token_minter.rb
Overview
Mints id_tokens and serves the OIDC discovery + JWKS documents.
Two signing modes:
:hs256 (default) — a shared symmetric key. Matches the original emulator's
"consumers don't verify" behaviour; simplest for local dev.
:rs256 — an RSA keypair (persisted under config_dir) with a published JWKS,
so real OIDC clients that DO verify signatures work out of the box.
Instance Method Summary collapse
- #discovery ⇒ Object
- #id_token(identity, nonce: nil, audience: nil) ⇒ Object
-
#initialize(config) ⇒ TokenMinter
constructor
A new instance of TokenMinter.
- #jwks ⇒ Object
- #payload(identity, nonce: nil, audience: nil) ⇒ Object
Constructor Details
#initialize(config) ⇒ TokenMinter
Returns a new instance of TokenMinter.
12 13 14 |
# File 'lib/identizer/token_minter.rb', line 12 def initialize(config) @config = config end |
Instance Method Details
#discovery ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/identizer/token_minter.rb', line 47 def discovery base = @config.base_url { "issuer" => @config.issuer, "authorization_endpoint" => "#{base}/v1/authorize", "token_endpoint" => "#{base}/v1/token", "userinfo_endpoint" => "#{base}/userinfo", "jwks_uri" => "#{base}/.well-known/jwks.json", "introspection_endpoint" => "#{base}/introspect", "revocation_endpoint" => "#{base}/revoke", "end_session_endpoint" => "#{base}/v1/logout", "response_types_supported" => ["code"], "grant_types_supported" => %w[authorization_code refresh_token], "code_challenge_methods_supported" => %w[S256 plain], "subject_types_supported" => ["public"], "id_token_signing_alg_values_supported" => [@config.rs256? ? "RS256" : "HS256"], "scopes_supported" => %w[openid email profile] } end |
#id_token(identity, nonce: nil, audience: nil) ⇒ Object
16 17 18 19 20 21 22 23 |
# File 'lib/identizer/token_minter.rb', line 16 def id_token(identity, nonce: nil, audience: nil) payload = payload(identity, nonce: nonce, audience: audience) if @config.rs256? JWT.encode(payload, rsa_key, "RS256", { kid: jwk.kid }) else JWT.encode(payload, @config.hs256_key, "HS256") end end |
#jwks ⇒ Object
41 42 43 44 45 |
# File 'lib/identizer/token_minter.rb', line 41 def jwks return { "keys" => [] } unless @config.rs256? { "keys" => [jwk.export] } end |
#payload(identity, nonce: nil, audience: nil) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/identizer/token_minter.rb', line 25 def payload(identity, nonce: nil, audience: nil) now = Time.now.to_i registered = { "iss" => @config.issuer, # Audience is the requesting client_id when known, so OIDC clients that # validate `aud == client_id` accept the token; falls back to a constant. "aud" => audience.to_s.empty? ? "identizer" : audience, "iat" => now, "exp" => now + 3600 # id_token lifetime (intentionally separate from access_token_ttl) } registered["nonce"] = nonce unless nonce.to_s.empty? # Registered claims always win over identity-derived ones, so a directory # attribute can never forge iss/aud/exp/iat/nonce. identity.to_h.merge(registered) end |