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] }