Class: OmniAuth::Strategies::Himari

Inherits:
OAuth2
  • Object
show all
Defined in:
lib/omniauth/strategies/himari.rb

Defined Under Namespace

Classes: AccessToken, ConfigurationError, IdToken, IdTokenMissing, VerificationError

Instance Method Summary collapse

Instance Method Details

#authorize_paramsObject



124
125
126
127
128
129
# File 'lib/omniauth/strategies/himari.rb', line 124

def authorize_params
  super.tap do |params|
    params[:scope] = 'openid'
    params[:prompt] = request.GET['prompt'] if request.GET['prompt']
  end
end

#callback_urlObject



116
117
118
# File 'lib/omniauth/strategies/himari.rb', line 116

def callback_url
  options[:redirect_uri] || (full_host + callback_path) # https://github.com/omniauth/omniauth-oauth2/pull/142
end

#clientObject

Raises:



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/omniauth/strategies/himari.rb', line 34

def client
  options.client_options.site ||= options.site
  options.client_options.authorize_url ||= '/oidc/authorize'
  options.client_options.token_url ||= '/public/oidc/token'
  options.client_options.userinfo_url ||= '/public/oidc/userinfo'
  options.client_options.access_token_class ||= AccessToken # https://gitlab.com/oauth-xx/oauth2/-/issues/628

  options.client_options.connection_opts ||= {}
  options.client_options.connection_opts[:headers] ||= {}
  options.client_options.connection_opts[:headers] = {
    'User-Agent' => user_agent,
  }.merge(options.client_options.connection_opts[:headers])

  raise ConfigurationError, "client_id and client_secret is required" unless options.client_id && options.client_secret
  raise ConfigurationError, "site is required" unless options.client_options.site
  super
end

#faradayObject



109
110
111
112
113
114
# File 'lib/omniauth/strategies/himari.rb', line 109

def faraday
  @faraday ||= Faraday.new(options.site, headers: {'User-Agent' => user_agent}) do |b|
    b.response :json
    b.response :raise_error
  end
end

#id_tokenObject



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/omniauth/strategies/himari.rb', line 133

def id_token
  @id_token ||= begin
    jwt = access_token.params['id_token'] or raise(IdTokenMissing, 'id_token is missing')
    retval = IdToken.new(*JWT.decode(
      jwt,
      nil,
      true,
      {
        algorithms: jwks.map { |k| k[:alg] }.compact.uniq,
        jwks: jwks,
        verify_aud: true,
        aud: options.client_id,
        verify_iss: true,
        iss: options.site,
        verify_expiration: true,
      }.merge(options.verify_options)
    ))
    verify_at_hash!(retval)
    retval
  end
end

#jwksObject



155
156
157
158
159
# File 'lib/omniauth/strategies/himari.rb', line 155

def jwks
  JWT::JWK::Set.new(jwks_json).tap do |set|
    set.filter! { |k| k[:use] == 'sig' }
  end
end

#jwks_jsonObject



161
162
163
164
165
# File 'lib/omniauth/strategies/himari.rb', line 161

def jwks_json
  faraday.get(options.jwks_url || 'public/jwks').body
rescue Faraday::Error => e
  raise JwksUnavailable, "failed to retrieve jwks; #{e.inspect}"
end

#raw_infoObject



105
106
107
# File 'lib/omniauth/strategies/himari.rb', line 105

def raw_info
  @raw_info ||= (!skip_info? && options.use_userinfo) ? access_token.get('/public/oidc/userinfo').parsed : id_token.claims
end

#user_agentObject



120
121
122
# File 'lib/omniauth/strategies/himari.rb', line 120

def user_agent
  options.user_agent || "OmniauthHimari/#{Omniauth::Himari::VERSION}"
end

#verify_at_hash!(id_token) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/omniauth/strategies/himari.rb', line 84

def verify_at_hash!(id_token)
  return unless options.verify_at_hash

  function = case id_token.header['alg'] # this is safe as we've verified
  when 'ES256', 'RS256'; Digest::SHA256
  when 'ES384'; Digest::SHA384
  when 'ES512'; Digest::SHA512
  else
    raise VerificationError, "unknown hash function to verify at_hash for #{id_token.header['alg']}"
  end

  dgst = function.digest(access_token.token)
  expected_at_hash = Base64.urlsafe_encode64(dgst[0, dgst.size/2], padding: false)

  given_at_hash = id_token.claims['at_hash']

  unless given_at_hash == expected_at_hash
    raise VerificationError, "at_hash mismatch #{given_at_hash.inspect}, #{expected_at_hash.inspect}"
  end
end