Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change Log

## v3.1.1 (2025-09-12)

* Validates the JWT `iss` (issuer) claim for `consumers` tenants properly, using the global GUID for that use case, resolving #51 (reported by @2called-chaos)

## v3.1.0 (2025-06-17)

* Provides a way to ignore TID when constructing a user UID, easing migration from v2.x, via the new `ignore_tid` option, resolving #42 (reported by @s-andringa)
Expand Down
4 changes: 2 additions & 2 deletions lib/omniauth/entra_id/version.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module OmniAuth
module Entra
module Id
VERSION = "3.1.0"
DATE = "2025-06-17"
VERSION = "3.1.1"
DATE = "2025-09-12"
end
end
end
13 changes: 10 additions & 3 deletions lib/omniauth/strategies/entra_id.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ class EntraId < OmniAuth::Strategies::OAuth2
option :ignore_tid, false
option :jwt_leeway, 60

DEFAULT_SCOPE = 'openid profile email'
COMMON_TENANT_ID = 'common'
AD_FS_TENANT_ID = 'adfs'
DEFAULT_SCOPE = 'openid profile email'
COMMON_TENANT_ID = 'common'
AD_FS_TENANT_ID = 'adfs'
ORGANIZATIONS_TENANT_ID = 'organizations'
CONSUMERS_TENANT_ID = 'consumers'
CONSUMERS_TENANT_GUID = '9188040d-6c67-4c5b-b112-36a304b66dad'

# The tenant_provider argument is how the provider class is eventually
# passed to us, if one is used instead of an options Hash.
Expand Down Expand Up @@ -160,6 +163,8 @@ def raw_info
# for AD FS local instances, as we don't put a valid tenant ID in its
# place, but "adfs" (see AD_FS_TENANT_ID) instead.
#
# TODO: Unclear about approach to use for ORGANIZATIONS_TENANT_ID.
#
do_not_verify = (
options.tenant_id.nil? ||
options.tenant_id == COMMON_TENANT_ID ||
Expand All @@ -168,6 +173,8 @@ def raw_info

issuer = if do_not_verify
nil
elsif options.tenant_id == CONSUMERS_TENANT_ID
"#{options.base_url || BASE_URL}/#{CONSUMERS_TENANT_GUID}/v2.0"
else
"#{options.base_url || BASE_URL}/#{options.tenant_id}/v2.0"
end
Expand Down
2 changes: 1 addition & 1 deletion omniauth-entra-id.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency 'jwt', '>= 2.9.2'
s.add_runtime_dependency 'omniauth-oauth2', '~> 1.8'

s.add_development_dependency 'debug', '~> 1.10'
s.add_development_dependency 'debug', '~> 1.11'
s.add_development_dependency 'rake', '~> 13.3'
s.add_development_dependency 'rspec', '~> 3.13'
end
22 changes: 22 additions & 0 deletions spec/omniauth/strategies/entra_id_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,28 @@ def ignore_tid?
expect { subject.info }.to_not raise_error()
end
end # "context '"common" tenant specified' do"

context '"consumers" tenant specified' do
subject do
OmniAuth::Strategies::EntraId.new(app, {client_id: 'id', client_secret: 'secret', tenant_id: OmniAuth::Strategies::EntraId::CONSUMERS_TENANT_ID})
end

it 'raises an error as the issuer *is* checked' do
expect { subject.info }.to raise_error(JWT::InvalidIssuerError)
end

context 'with the "magic" tenant ID' do
let(:id_token_info) do
hash = super()
hash['iss'] = 'https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0'
hash
end

it 'raises no error' do
expect { subject.info }.to_not raise_error()
end
end # "context 'with the "magic" tenant ID' do"
end # "context '"consumers" tenant specified' do"
end # "context 'multi-tenant, AD FS' do"
end # "context 'issuers' do"

Expand Down