mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-26 17:51:13 +08:00
Merge pull request #2263 from okriuchykhin/ok_SCI_4142
Implement SSO with Azure AD [SCI-4142]
This commit is contained in:
commit
792e6f2eb9
16 changed files with 222 additions and 14 deletions
18
.rubocop.yml
18
.rubocop.yml
|
@ -14,12 +14,12 @@ AllCops:
|
||||||
Layout/AccessModifierIndentation:
|
Layout/AccessModifierIndentation:
|
||||||
EnforcedStyle: indent
|
EnforcedStyle: indent
|
||||||
|
|
||||||
Layout/AlignHash:
|
Layout/HashAlignment:
|
||||||
EnforcedHashRocketStyle: key
|
EnforcedHashRocketStyle: key
|
||||||
EnforcedColonStyle: key
|
EnforcedColonStyle: key
|
||||||
EnforcedLastArgumentHashStyle: ignore_implicit
|
EnforcedLastArgumentHashStyle: ignore_implicit
|
||||||
|
|
||||||
Layout/AlignParameters:
|
Layout/ParameterAlignment:
|
||||||
EnforcedStyle: with_first_parameter
|
EnforcedStyle: with_first_parameter
|
||||||
|
|
||||||
Style/AndOr:
|
Style/AndOr:
|
||||||
|
@ -83,7 +83,7 @@ Naming/FileName:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
Exclude: []
|
Exclude: []
|
||||||
|
|
||||||
Layout/IndentFirstParameter:
|
Layout/FirstParameterIndentation:
|
||||||
EnforcedStyle: consistent
|
EnforcedStyle: consistent
|
||||||
|
|
||||||
Style/For:
|
Style/For:
|
||||||
|
@ -111,10 +111,10 @@ Layout/IndentationConsistency:
|
||||||
Layout/IndentationWidth:
|
Layout/IndentationWidth:
|
||||||
Width: 2
|
Width: 2
|
||||||
|
|
||||||
Layout/IndentFirstArrayElement:
|
Layout/FirstArrayElementIndentation:
|
||||||
EnforcedStyle: special_inside_parentheses
|
EnforcedStyle: special_inside_parentheses
|
||||||
|
|
||||||
Layout/IndentFirstHashElement:
|
Layout/FirstHashElementIndentation:
|
||||||
EnforcedStyle: special_inside_parentheses
|
EnforcedStyle: special_inside_parentheses
|
||||||
|
|
||||||
Style/Next:
|
Style/Next:
|
||||||
|
@ -197,9 +197,9 @@ Naming/PredicateName:
|
||||||
- is_
|
- is_
|
||||||
- has_
|
- has_
|
||||||
- have_
|
- have_
|
||||||
NamePrefixBlacklist:
|
ForbiddenPrefixes:
|
||||||
- is_
|
- is_
|
||||||
NameWhitelist:
|
AllowedMethods:
|
||||||
- is_a?
|
- is_a?
|
||||||
Exclude:
|
Exclude:
|
||||||
- spec/**/*
|
- spec/**/*
|
||||||
|
@ -282,7 +282,7 @@ Style/TernaryParentheses:
|
||||||
EnforcedStyle: require_no_parentheses
|
EnforcedStyle: require_no_parentheses
|
||||||
AllowSafeAssignment: true
|
AllowSafeAssignment: true
|
||||||
|
|
||||||
Layout/TrailingBlankLines:
|
Layout/TrailingEmptyLines:
|
||||||
EnforcedStyle: final_newline
|
EnforcedStyle: final_newline
|
||||||
|
|
||||||
Style/TrailingCommaInArguments:
|
Style/TrailingCommaInArguments:
|
||||||
|
@ -411,7 +411,7 @@ Lint/UnusedMethodArgument:
|
||||||
Lint/EachWithObjectArgument:
|
Lint/EachWithObjectArgument:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
Lint/HandleExceptions:
|
Lint/SuppressedException:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Lint/LiteralAsCondition:
|
Lint/LiteralAsCondition:
|
||||||
|
|
1
Gemfile
1
Gemfile
|
@ -23,6 +23,7 @@ gem 'yomu', git: 'https://github.com/biosistemika/yomu', branch: 'master'
|
||||||
# Gems for OAuth2 subsystem
|
# Gems for OAuth2 subsystem
|
||||||
gem 'doorkeeper', '>= 4.6'
|
gem 'doorkeeper', '>= 4.6'
|
||||||
gem 'omniauth'
|
gem 'omniauth'
|
||||||
|
gem 'omniauth-azure-activedirectory'
|
||||||
gem 'omniauth-linkedin-oauth2'
|
gem 'omniauth-linkedin-oauth2'
|
||||||
|
|
||||||
# TODO: remove this when omniauth gem resolves CVE issues
|
# TODO: remove this when omniauth gem resolves CVE issues
|
||||||
|
|
|
@ -373,6 +373,9 @@ GEM
|
||||||
omniauth (1.9.0)
|
omniauth (1.9.0)
|
||||||
hashie (>= 3.4.6, < 3.7.0)
|
hashie (>= 3.4.6, < 3.7.0)
|
||||||
rack (>= 1.6.2, < 3)
|
rack (>= 1.6.2, < 3)
|
||||||
|
omniauth-azure-activedirectory (1.0.0)
|
||||||
|
jwt (~> 1.5)
|
||||||
|
omniauth (~> 1.1)
|
||||||
omniauth-linkedin-oauth2 (1.0.0)
|
omniauth-linkedin-oauth2 (1.0.0)
|
||||||
omniauth-oauth2
|
omniauth-oauth2
|
||||||
omniauth-oauth2 (1.6.0)
|
omniauth-oauth2 (1.6.0)
|
||||||
|
@ -656,6 +659,7 @@ DEPENDENCIES
|
||||||
newrelic_rpm
|
newrelic_rpm
|
||||||
nokogiri (~> 1.10.3)
|
nokogiri (~> 1.10.3)
|
||||||
omniauth
|
omniauth
|
||||||
|
omniauth-azure-activedirectory
|
||||||
omniauth-linkedin-oauth2
|
omniauth-linkedin-oauth2
|
||||||
omniauth-rails_csrf_protection (~> 0.1)
|
omniauth-rails_csrf_protection (~> 0.1)
|
||||||
overcommit
|
overcommit
|
||||||
|
|
|
@ -380,6 +380,16 @@ a[data-toggle="tooltip"] {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.azure-sign-in-actions {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
|
||||||
|
.btn-azure-ad {
|
||||||
|
background-color: $office-ms-word;
|
||||||
|
color: $color-white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.navbar-secondary {
|
.navbar-secondary {
|
||||||
-webkit-transition: all 0.5s ease;
|
-webkit-transition: all 0.5s ease;
|
||||||
-moz-transition: all 0.5s ease;
|
-moz-transition: all 0.5s ease;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Users
|
module Users
|
||||||
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||||
include UsersGenerator
|
include UsersGenerator
|
||||||
|
@ -13,6 +15,53 @@ module Users
|
||||||
# def twitter
|
# def twitter
|
||||||
# end
|
# end
|
||||||
|
|
||||||
|
def customazureactivedirectory
|
||||||
|
auth = request.env['omniauth.auth']
|
||||||
|
provider_id = auth.dig(:extra, :raw_info, :id_token_claims, :aud)
|
||||||
|
provider_conf = Rails.configuration.x.azure_ad_apps[provider_id]
|
||||||
|
raise StandardError, 'No matching Azure AD provider config found' if provider_conf.empty?
|
||||||
|
|
||||||
|
auth.provider = provider_conf[:provider]
|
||||||
|
|
||||||
|
return redirect_to connected_accounts_path if current_user
|
||||||
|
|
||||||
|
email = auth.info.email
|
||||||
|
email ||= auth.dig(:extra, :raw_info, :id_token_claims, :emails)&.first
|
||||||
|
user = User.from_omniauth(auth)
|
||||||
|
if user
|
||||||
|
# User found in database so just sign in him
|
||||||
|
sign_in_and_redirect(user)
|
||||||
|
elsif email.present?
|
||||||
|
user = User.find_by(email: email)
|
||||||
|
|
||||||
|
if user.blank?
|
||||||
|
# Create new user and identity
|
||||||
|
User.create_from_omniauth!(auth)
|
||||||
|
sign_in_and_redirect(user)
|
||||||
|
elsif provider_conf[:auto_link_on_sign_in]
|
||||||
|
# Link to existing local account
|
||||||
|
user.user_identities.create!(provider: auth.provider, uid: auth.uid)
|
||||||
|
sign_in_and_redirect(user)
|
||||||
|
else
|
||||||
|
# Cannot do anything with it, so just return an error
|
||||||
|
error_message = I18n.t('devise.azure.errors.no_local_user_map')
|
||||||
|
redirect_to after_omniauth_failure_path_for(resource_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue StandardError => e
|
||||||
|
Rails.logger.error e.message
|
||||||
|
Rails.logger.error e.backtrace.join("\n")
|
||||||
|
error_message = I18n.t('devise.azure.errors.failed_to_save') if e.is_a?(ActiveRecord::RecordInvalid)
|
||||||
|
error_message ||= I18n.t('devise.azure.errors.generic')
|
||||||
|
redirect_to after_omniauth_failure_path_for(resource_name)
|
||||||
|
ensure
|
||||||
|
if error_message
|
||||||
|
set_flash_message(:alert, :failure, kind: I18n.t('devise.azure.provider_name'), reason: error_message)
|
||||||
|
else
|
||||||
|
set_flash_message(:notice, :success, kind: I18n.t('devise.azure.provider_name'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def linkedin
|
def linkedin
|
||||||
auth_hash = request.env['omniauth.auth']
|
auth_hash = request.env['omniauth.auth']
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,20 @@ module Users
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
current_user.user_identities.where(provider: params.require(:provider)).take&.destroy!
|
if Rails.configuration.x.azure_ad_apps.select { |_, v| v[:provider] == params[:provider] }.present?
|
||||||
|
provider = params[:provider]
|
||||||
|
else
|
||||||
|
flash[:error] = t('users.settings.account.connected_accounts.errors.not_found')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
__send__("#{provider}_pre_destroy".to_sym) if respond_to?("#{provider}_pre_destroy".to_sym, true)
|
||||||
|
current_user.user_identities.where(provider: provider).take&.destroy!
|
||||||
|
end
|
||||||
|
flash[:success] = t('users.settings.account.connected_accounts.unlink_success')
|
||||||
|
rescue StandardError
|
||||||
|
flash[:error] ||= t('users.settings.account.connected_accounts.errors.generic')
|
||||||
|
ensure
|
||||||
@linked_accounts = current_user.user_identities.pluck(:provider)
|
@linked_accounts = current_user.user_identities.pluck(:provider)
|
||||||
render :index
|
render :index
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,6 @@ module AddonsHelper
|
||||||
Rails::Engine
|
Rails::Engine
|
||||||
.subclasses
|
.subclasses
|
||||||
.select { |c| c.name.start_with?('Scinote') }
|
.select { |c| c.name.start_with?('Scinote') }
|
||||||
.map(&:parent)
|
.map(&:module_parent)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -297,6 +297,20 @@ class User < ApplicationRecord
|
||||||
.take
|
.take
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.create_from_omniauth!(auth)
|
||||||
|
full_name = "#{auth.info.first_name} #{auth.info.last_name}"
|
||||||
|
user = User.new(full_name: full_name,
|
||||||
|
initials: generate_initials(full_name),
|
||||||
|
email: email,
|
||||||
|
password: generate_user_password)
|
||||||
|
User.transaction do
|
||||||
|
user.save!
|
||||||
|
user.user_identities.create!(provider: auth.provider, uid: auth.uid)
|
||||||
|
user.update!(confirmed_at: user.created_at)
|
||||||
|
end
|
||||||
|
user
|
||||||
|
end
|
||||||
|
|
||||||
# Search all active users for username & email. Can
|
# Search all active users for username & email. Can
|
||||||
# also specify which team to ignore.
|
# also specify which team to ignore.
|
||||||
def self.search(
|
def self.search(
|
||||||
|
|
|
@ -42,7 +42,7 @@ module Api
|
||||||
end
|
end
|
||||||
|
|
||||||
# Decode token payload and verify it's signature.
|
# Decode token payload and verify it's signature.
|
||||||
payload, = JWT.decode(
|
payload, header = JWT.decode(
|
||||||
token,
|
token,
|
||||||
OpenSSL::PKey::RSA.new(fetch_rsa_key(k_id, app_id)),
|
OpenSSL::PKey::RSA.new(fetch_rsa_key(k_id, app_id)),
|
||||||
true,
|
true,
|
||||||
|
@ -54,7 +54,7 @@ module Api
|
||||||
iss: app_config[:iss],
|
iss: app_config[:iss],
|
||||||
nbf_leeway: LEEWAY
|
nbf_leeway: LEEWAY
|
||||||
)
|
)
|
||||||
HashWithIndifferentAccess.new(payload)
|
[HashWithIndifferentAccess.new(payload), HashWithIndifferentAccess.new(header)]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
7
app/views/users/shared/_azure_sign_in_links.html.erb
Normal file
7
app/views/users/shared/_azure_sign_in_links.html.erb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<% Rails.configuration.x.azure_ad_apps.select { |uid, config| config[:enable_sign_in] }.each do |uid, config| %>
|
||||||
|
<div class="form-group">
|
||||||
|
<%= form_tag user_customazureactivedirectory_omniauth_authorize_path(provider: config[:provider]), method: :post do %>
|
||||||
|
<%= submit_tag config[:sign_in_label], class: 'btn btn-azure-ad' %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
|
@ -37,4 +37,8 @@
|
||||||
<% end -%>
|
<% end -%>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
|
||||||
|
<div class="azure-sign-in-actions">
|
||||||
|
<%= render partial: "users/shared/azure_sign_in_links", locals: { resource_name: resource_name } %>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
Rails.application.configure do
|
Rails.application.configure do
|
||||||
vars = ENV.select { |name, _| name =~ /^[[:alnum:]]*_AZURE_AD_APP_ID/ }
|
vars = ENV.select { |name, _| name =~ /^[[:alnum:]]*_AZURE_AD_APP_ID/ }
|
||||||
|
config.x.azure_ad_apps = HashWithIndifferentAccess.new if vars.present?
|
||||||
|
|
||||||
vars.each do |name, value|
|
vars.each do |name, value|
|
||||||
app_name = name.sub('_AZURE_AD_APP_ID', '')
|
app_name = name.sub('_AZURE_AD_APP_ID', '')
|
||||||
config.x.azure_ad_apps[value] = {}
|
config.x.azure_ad_apps[value] = {}
|
||||||
|
@ -20,5 +22,16 @@ Rails.application.configure do
|
||||||
raise StandardError, "No PROVIDER_NAME for #{app_name} Azure app" unless provider
|
raise StandardError, "No PROVIDER_NAME for #{app_name} Azure app" unless provider
|
||||||
|
|
||||||
config.x.azure_ad_apps[value][:provider] = provider
|
config.x.azure_ad_apps[value][:provider] = provider
|
||||||
|
|
||||||
|
config.x.azure_ad_apps[value][:enable_sign_in] = ENV["#{app_name}_AZURE_AD_ENABLE_SIGN_IN"] == 'true'
|
||||||
|
|
||||||
|
next unless config.x.azure_ad_apps[value][:enable_sign_in]
|
||||||
|
|
||||||
|
config.x.azure_ad_apps[value][:sign_in_label] = ENV["#{app_name}_AZURE_AD_SIGN_IN_LABEL"] || 'Sign in with Azure AD'
|
||||||
|
config.x.azure_ad_apps[value][:auto_link_on_sign_in] = ENV["#{app_name}_AZURE_AD_AUTO_LINK_ON_SIGN_IN"] == 'true'
|
||||||
|
|
||||||
|
if ENV["#{app_name}_AZURE_AD_SIGN_IN_POLICY"]
|
||||||
|
config.x.azure_ad_apps[value][:sign_in_policy] = ENV["#{app_name}_AZURE_AD_SIGN_IN_POLICY"]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -73,7 +73,7 @@ class Extends
|
||||||
'RepositoryListValue' => 'list',
|
'RepositoryListValue' => 'list',
|
||||||
'RepositoryAssetValue' => 'file' }
|
'RepositoryAssetValue' => 'file' }
|
||||||
|
|
||||||
OMNIAUTH_PROVIDERS = [:linkedin]
|
OMNIAUTH_PROVIDERS = [:linkedin, :customazureactivedirectory]
|
||||||
|
|
||||||
INITIAL_USER_OPTIONS = {}
|
INITIAL_USER_OPTIONS = {}
|
||||||
|
|
||||||
|
|
37
config/initializers/omniauth.rb
Normal file
37
config/initializers/omniauth.rb
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'omniauth/strategies/custom_azure_active_directory'
|
||||||
|
|
||||||
|
SETUP_PROC = lambda do |env|
|
||||||
|
providers = Rails.configuration.x.azure_ad_apps.select { |_, v| v[:enable_sign_in] == true }
|
||||||
|
raise StandardError, 'No Azure AD config available for sign in' if providers.empty?
|
||||||
|
|
||||||
|
req = Rack::Request.new(env)
|
||||||
|
|
||||||
|
if providers.size > 1
|
||||||
|
if req.params['id_token'].present? # Callback phase
|
||||||
|
unverified_jwt_payload, = JWT.decode(req.params['id_token'], nil, false)
|
||||||
|
raise StandardError, 'No Azure AD config available for sign in' if providers[unverified_jwt_payload['aud']].blank?
|
||||||
|
|
||||||
|
provider_id = unverified_jwt_payload['aud']
|
||||||
|
else # Authorization phase
|
||||||
|
raise ActionController::ParameterMissing, 'Provider name is missing' if req.params['provider'].blank?
|
||||||
|
|
||||||
|
provider_id = providers.select { |_, v| v[:provider] == req.params['provider'] }.keys.first
|
||||||
|
raise StandardError, 'No Azure AD config available for sign in' if provider_id.blank?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
provider_id ||= providers.keys.first
|
||||||
|
provider_conf = providers[provider_id]
|
||||||
|
|
||||||
|
env['omniauth.strategy'].options[:client_id] = provider_id
|
||||||
|
env['omniauth.strategy'].options[:openid_config_url] = provider_conf[:conf_url]
|
||||||
|
env['omniauth.strategy'].options[:sign_in_policy] = provider_conf[:sign_in_policy]
|
||||||
|
end
|
||||||
|
|
||||||
|
Rails.application.config.middleware.use OmniAuth::Builder do
|
||||||
|
provider OmniAuth::Strategies::CustomAzureActiveDirectory, setup: SETUP_PROC
|
||||||
|
end
|
||||||
|
|
||||||
|
OmniAuth.config.logger = Rails.logger
|
|
@ -51,6 +51,12 @@ en:
|
||||||
complete_sign_up: "You have to complete the sign up process"
|
complete_sign_up: "You have to complete the sign up process"
|
||||||
email_already_taken: "SciNote account with email %{email} alreday exists"
|
email_already_taken: "SciNote account with email %{email} alreday exists"
|
||||||
failed_to_save: "Failed to create new user"
|
failed_to_save: "Failed to create new user"
|
||||||
|
azure:
|
||||||
|
provider_name: "Azure Active Directory"
|
||||||
|
errors:
|
||||||
|
generic: "Failed to sign in user"
|
||||||
|
no_local_user_map: "No local user record found"
|
||||||
|
failed_to_save: "Failed to create new user"
|
||||||
|
|
||||||
doorkeeper:
|
doorkeeper:
|
||||||
authorizations:
|
authorizations:
|
||||||
|
@ -1488,6 +1494,7 @@ en:
|
||||||
head_title: "Settings | Connected Accounts"
|
head_title: "Settings | Connected Accounts"
|
||||||
title: "Connected Accounts"
|
title: "Connected Accounts"
|
||||||
not_connected: "You have no Connected accounts"
|
not_connected: "You have no Connected accounts"
|
||||||
|
unlink_success: "Sucessfully unlinked"
|
||||||
azure_ad:
|
azure_ad:
|
||||||
title: "Your Azure AD Account"
|
title: "Your Azure AD Account"
|
||||||
connect_hint: "Allows you to sign in with your Azure AD account."
|
connect_hint: "Allows you to sign in with your Azure AD account."
|
||||||
|
@ -1497,6 +1504,9 @@ en:
|
||||||
title: "Unlink Azure AD account?"
|
title: "Unlink Azure AD account?"
|
||||||
description_1: "Are you sure you would like unlink Azure AD and SciNote accounts?"
|
description_1: "Are you sure you would like unlink Azure AD and SciNote accounts?"
|
||||||
submit_button: "Submit"
|
submit_button: "Submit"
|
||||||
|
errors:
|
||||||
|
not_found: "You have no Connected accounts for this provider"
|
||||||
|
generic: "Unable to unlink linked account"
|
||||||
teams:
|
teams:
|
||||||
head_title: "Settings | Teams"
|
head_title: "Settings | Teams"
|
||||||
breadcrumbs:
|
breadcrumbs:
|
||||||
|
|
46
lib/omniauth/strategies/custom_azure_active_directory.rb
Normal file
46
lib/omniauth/strategies/custom_azure_active_directory.rb
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module OmniAuth
|
||||||
|
module Strategies
|
||||||
|
class CustomAzureActiveDirectory < AzureActiveDirectory
|
||||||
|
include OmniAuth::Strategy
|
||||||
|
|
||||||
|
option :openid_config_url
|
||||||
|
option :sign_in_policy
|
||||||
|
|
||||||
|
# Azure doesn't allow query params in callback URL
|
||||||
|
def callback_url
|
||||||
|
full_host + script_name + callback_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def openid_config_url
|
||||||
|
options[:openid_config_url]
|
||||||
|
end
|
||||||
|
|
||||||
|
def authorize_endpoint_url
|
||||||
|
uri = URI(openid_config['authorization_endpoint'])
|
||||||
|
params = {
|
||||||
|
client_id: client_id,
|
||||||
|
redirect_uri: callback_url,
|
||||||
|
response_mode: response_mode,
|
||||||
|
response_type: response_type,
|
||||||
|
nonce: new_nonce,
|
||||||
|
scope: 'openid'
|
||||||
|
}
|
||||||
|
params[:p] = options[:sign_in_policy] if options[:sign_in_policy].present?
|
||||||
|
|
||||||
|
uri.query = URI.encode_www_form(params)
|
||||||
|
uri.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_and_parse_id_token(id_token)
|
||||||
|
jwt_claims, jwt_header = Api::AzureJwt.decode(id_token)
|
||||||
|
return jwt_claims, jwt_header if jwt_claims['nonce'] == read_nonce
|
||||||
|
|
||||||
|
raise JWT::DecodeError, 'Returned nonce did not match.'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
OmniAuth.config.add_camelization 'custom_azure_activedirectory', 'CustomAzureActiveDirectory'
|
Loading…
Reference in a new issue