lib/rodauth/features/oauth_jwt_base.rb in rodauth-oauth-1.0.0.pre.beta1 vs lib/rodauth/features/oauth_jwt_base.rb in rodauth-oauth-1.0.0.pre.beta2
- old
+ new
@@ -61,11 +61,15 @@
Array(grant_or_claims["aud"]).include?(oauth_application[oauth_applications_client_id_column])
end
end
def jwt_subject(oauth_grant, client_application = oauth_application)
- oauth_grant[oauth_grants_account_id_column] || client_application[oauth_applications_client_id_column]
+ account_id = oauth_grant[oauth_grants_account_id_column]
+
+ return account_id.to_s if account_id
+
+ client_application[oauth_applications_client_id_column]
end
def oauth_server_metadata_body(path = nil)
metadata = super
metadata.merge! \
@@ -205,18 +209,27 @@
token = JSON::JWT.decode(token, jwe_key).plain_text
end
claims = if is_authorization_server?
if jwks
+ jwks = jwks[:keys] if jwks.is_a?(Hash)
+
enc_algs = [jws_encryption_algorithm].compact
enc_meths = [jws_encryption_method].compact
sig_algs = jws_algorithm ? [jws_algorithm] : jwks.select { |k| k[:use] == "sig" }.map { |k| k[:alg] }
sig_algs = sig_algs.compact.map(&:to_sym)
- jws = JSON::JWT.decode(token, JSON::JWK::Set.new({ keys: jwks }), enc_algs + sig_algs, enc_meths)
- jws = JSON::JWT.decode(jws.plain_text, JSON::JWK::Set.new({ keys: jwks }), sig_algs) if jws.is_a?(JSON::JWE)
+ # JWKs may be set up without a KID, when there's a single one
+ if jwks.size == 1 && !jwks[0][:kid]
+ key = jwks[0]
+ jwk_key = JSON::JWK.new(key)
+ jws = JSON::JWT.decode(token, jwk_key)
+ else
+ jws = JSON::JWT.decode(token, JSON::JWK::Set.new({ keys: jwks }), enc_algs + sig_algs, enc_meths)
+ jws = JSON::JWT.decode(jws.plain_text, JSON::JWK::Set.new({ keys: jwks }), sig_algs) if jws.is_a?(JSON::JWE)
+ end
jws
elsif jws_key
JSON::JWT.decode(token, jws_key)
end
elsif (jwks = auth_server_jwks_set)
@@ -277,11 +290,11 @@
def jwk_export(key)
JWT::JWK.new(key).export
end
def jwt_encode(payload,
- signing_algorithm: oauth_jwt_keys.keys.first)
+ signing_algorithm: oauth_jwt_keys.keys.first, **)
headers = {}
key = oauth_jwt_keys[signing_algorithm] || _jwt_key
key = key.first if key.is_a?(Array)
@@ -366,11 +379,21 @@
end
# decode jwt
claims = if is_authorization_server?
if jwks
- algorithms = jws_algorithm ? [jws_algorithm] : jwks.select { |k| k[:use] == "sig" }.map { |k| k[:alg] }
- JWT.decode(token, nil, true, algorithms: algorithms, jwks: { keys: jwks }, **verify_claims_params).first
+ jwks = jwks[:keys] if jwks.is_a?(Hash)
+
+ # JWKs may be set up without a KID, when there's a single one
+ if jwks.size == 1 && !jwks[0][:kid]
+ key = jwks[0]
+ algo = key[:alg]
+ key = JWT::JWK.import(key).keypair
+ JWT.decode(token, key, true, algorithms: [algo], **verify_claims_params).first
+ else
+ algorithms = jws_algorithm ? [jws_algorithm] : jwks.select { |k| k[:use] == "sig" }.map { |k| k[:alg] }
+ JWT.decode(token, nil, true, algorithms: algorithms, jwks: { keys: jwks }, **verify_claims_params).first
+ end
elsif jws_key
JWT.decode(token, jws_key, true, algorithms: [jws_algorithm], **verify_claims_params).first
end
elsif (jwks = auth_server_jwks_set)
algorithms = jwks[:keys].select { |k| k[:use] == "sig" }.map { |k| k[:alg] }