reopen openid_connect gem to support AC encrypted jwt response
This commit is contained in:
parent
898df449d4
commit
3316dfc866
1 changed files with 56 additions and 0 deletions
|
@ -3,3 +3,59 @@ OpenIDConnect.logger = Rails.logger
|
|||
Rack::OAuth2.logger = Rails.logger
|
||||
# Webfinger.logger = Rails.logger
|
||||
SWD.logger = Rails.logger
|
||||
|
||||
# the openid_connect gem does not support
|
||||
# jwt format in the userinfo call.
|
||||
# A PR is open to improve the situation
|
||||
# https://github.com/nov/openid_connect/pull/54
|
||||
module OpenIDConnect
|
||||
class AccessToken < Rack::OAuth2::AccessToken::Bearer
|
||||
private
|
||||
|
||||
def jwk_loader
|
||||
JSON.parse(URI.parse(ENV['AGENT_CONNECT_JWKS']).read).deep_symbolize_keys
|
||||
end
|
||||
|
||||
def decode_jwt(requested_host, jwt)
|
||||
agent_connect_host = URI.parse(ENV['AGENT_CONNECT_BASE_URL']).host
|
||||
|
||||
if requested_host == agent_connect_host
|
||||
# rubocop:disable Lint/UselessAssignment
|
||||
JWT.decode(jwt, key = nil, verify = true, { algorithms: ['ES256'], jwks: jwk_loader })[0]
|
||||
# rubocop:enable Lint/UselessAssignment
|
||||
else
|
||||
raise "unknwon host : #{requested_host}"
|
||||
end
|
||||
end
|
||||
|
||||
def resource_request
|
||||
res = yield
|
||||
case res.status
|
||||
when 200
|
||||
hash = case parse_type_and_subtype(res.content_type)
|
||||
when 'application/jwt'
|
||||
requested_host = URI.parse(client.userinfo_endpoint).host
|
||||
decode_jwt(requested_host, res.body)
|
||||
when 'application/json'
|
||||
JSON.parse(res.body)
|
||||
end
|
||||
hash&.with_indifferent_access
|
||||
when 400
|
||||
raise BadRequest.new('API Access Faild', res)
|
||||
when 401
|
||||
raise Unauthorized.new('Access Token Invalid or Expired', res)
|
||||
when 403
|
||||
raise Forbidden.new('Insufficient Scope', res)
|
||||
else
|
||||
raise HttpError.new(res.status, 'Unknown HttpError', res)
|
||||
end
|
||||
end
|
||||
|
||||
# https://datatracker.ietf.org/doc/html/rfc2045#section-5.1
|
||||
# - type and subtype are the first member
|
||||
# they are case insensitive
|
||||
def parse_type_and_subtype(content_type)
|
||||
content_type.split(';')[0].strip.downcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue