Class: Himari::Services::UpstreamAuthentication
- Inherits:
-
Object
- Object
- Himari::Services::UpstreamAuthentication
- Defined in:
- lib/himari/services/upstream_authentication.rb
Defined Under Namespace
Classes: Result, UnauthorizedError
Class Method Summary collapse
- .from_request(request) ⇒ Object
-
.revalidate_from_request(session:, request:) ⇒ Object
Re-run claims/authn rules against an existing session, e.g.
Instance Method Summary collapse
- #check_authn(claims_result, session_data) ⇒ Object
- #derive_base_session(claims_result) ⇒ Object
-
#initialize(auth: nil, session: nil, grant_type: :initial, request: nil, claims_rules: [], authn_rules: [], logger: nil) ⇒ UpstreamAuthentication
constructor
A new instance of UpstreamAuthentication.
- #make_claims ⇒ Object
- #perform ⇒ Object
- #provider ⇒ Object
- #uid_for_log ⇒ Object
Constructor Details
#initialize(auth: nil, session: nil, grant_type: :initial, request: nil, claims_rules: [], authn_rules: [], logger: nil) ⇒ UpstreamAuthentication
Returns a new instance of UpstreamAuthentication.
47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/himari/services/upstream_authentication.rb', line 47 def initialize(auth: nil, session: nil, grant_type: :initial, request: nil, claims_rules: [], authn_rules: [], logger: nil) raise ArgumentError, "auth or session is required" if auth.nil? && session.nil? @request = request @auth = auth @session = session @grant_type = grant_type @claims_rules = claims_rules @authn_rules = authn_rules @logger = logger end |
Class Method Details
.from_request(request) ⇒ Object
60 61 62 63 64 65 66 67 68 69 |
# File 'lib/himari/services/upstream_authentication.rb', line 60 def self.from_request(request) new( auth: request.env.fetch('omniauth.auth'), grant_type: :initial, request: request, claims_rules: Himari::ProviderChain.new(request.env[Himari::Middlewares::ClaimsRule::RACK_KEY] || []).collect, authn_rules: Himari::ProviderChain.new(request.env[Himari::Middlewares::AuthenticationRule::RACK_KEY] || []).collect, logger: request.env['rack.logger'], ) end |
.revalidate_from_request(session:, request:) ⇒ Object
Re-run claims/authn rules against an existing session, e.g. on refresh_token grant.
75 76 77 78 79 80 81 82 83 84 |
# File 'lib/himari/services/upstream_authentication.rb', line 75 def self.revalidate_from_request(session:, request:) new( session: session, grant_type: :refresh_token, request: request, claims_rules: Himari::ProviderChain.new(request.env[Himari::Middlewares::ClaimsRule::RACK_KEY] || []).collect, authn_rules: Himari::ProviderChain.new(request.env[Himari::Middlewares::AuthenticationRule::RACK_KEY] || []).collect, logger: request.env['rack.logger'], ) end |
Instance Method Details
#check_authn(claims_result, session_data) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/himari/services/upstream_authentication.rb', line 139 def check_authn(claims_result, session_data) context = Himari::Decisions::Authentication::Context.new(provider: provider, claims: session_data.claims, user_data: session_data.user_data, request: @request, grant_type: @grant_type, refresh_info: @session&.refresh_info).freeze # Don't preseed decision.refresh_info from session; otherwise a no-op authn rule would clobber whatever # the claims rule wrote (via Claims#refresh_info=). Authn rules that want to preserve session.refresh_info # must read context.refresh_info and assign it explicitly. result = Himari::RuleProcessor.new(context, Himari::Decisions::Authentication.new).run(@authn_rules) @logger&.debug(Himari::LogLine.new('UpstreamAuthentication: authentication', objid: object_id.to_s(16), uid: uid_for_log, provider: provider, grant_type: @grant_type, authn_result: result.as_log)) raise UnauthorizedError.new(Result.new(claims_result, result, nil)) unless result.allowed result end |
#derive_base_session(claims_result) ⇒ Object
129 130 131 132 133 134 135 136 137 |
# File 'lib/himari/services/upstream_authentication.rb', line 129 def derive_base_session(claims_result) decision = claims_result.decision if @session # revalidation: keep existing handle/secret/expiry, refresh claims/user_data @session.with(claims: decision.claims, user_data: decision.user_data) else decision.output end end |
#make_claims ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/himari/services/upstream_authentication.rb', line 108 def make_claims context = Himari::Decisions::Claims::Context.new(request: @request, auth: @auth, provider: provider, grant_type: @grant_type, refresh_info: @session&.refresh_info).freeze result = Himari::RuleProcessor.new(context, Himari::Decisions::Claims.new).run(@claims_rules) @logger&.debug(Himari::LogLine.new('UpstreamAuthentication: claims', objid: object_id.to_s(16), uid: uid_for_log, provider: provider, grant_type: @grant_type, claims_result: result.as_log)) if result.explicit_deny @logger&.warn(Himari::LogLine.new('UpstreamAuthentication: claims explicit deny', objid: object_id.to_s(16), uid: uid_for_log, provider: provider, grant_type: @grant_type, claims_result: result.as_log)) raise UnauthorizedError.new(Result.new(result, nil, nil)) end begin claims = result.decision&.output&.claims raise UnauthorizedError.new(Result.new(result, nil, nil)) unless claims rescue Himari::Decisions::Claims::UninitializedError raise UnauthorizedError.new(Result.new(result, nil, nil)) end result end |
#perform ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/himari/services/upstream_authentication.rb', line 94 def perform @logger&.debug(Himari::LogLine.new('UpstreamAuthentication: perform', objid: object_id.to_s(16), uid: uid_for_log, provider: provider, grant_type: @grant_type)) claims_result = make_claims base = derive_base_session(claims_result) authn_result = check_authn(claims_result, base) final_refresh_info = authn_result.decision&.refresh_info || claims_result.decision&.refresh_info session_data = base.with(refresh_info: final_refresh_info) result = Result.new(claims_result, authn_result, session_data) @logger&.debug(Himari::LogLine.new('UpstreamAuthentication: result', objid: object_id.to_s(16), uid: uid_for_log, provider: provider, grant_type: @grant_type, result: result.as_log)) result end |
#provider ⇒ Object
86 87 88 |
# File 'lib/himari/services/upstream_authentication.rb', line 86 def provider (@auth && @auth[:provider]) || @session&.user_data&.dig(:provider) end |
#uid_for_log ⇒ Object
90 91 92 |
# File 'lib/himari/services/upstream_authentication.rb', line 90 def uid_for_log (@auth && @auth[:uid]) || @session&.claims&.dig(:sub) end |