@@ -36,17 +36,21 @@ def verify!
3636 # This means while it's not suitable for consistently identifying a user
3737 # (the domain might change), it is suitable for verifying membership in
3838 # a given domain.
39- return true if email_domain == upn_domain ||
40- skip_verification == true ||
41- ( skip_verification . is_a? ( Array ) && skip_verification . include? ( email_domain ) ) ||
42- domain_verified_jwt_claim
39+ # return true if email_domain == upn_domain ||
40+ # skip_verification == true ||
41+ # (skip_verification.is_a?(Array) && skip_verification.include?(email_domain))
42+
43+ # Try domain_verified_jwt_claim check
44+ xms_edov_result = check_xms_edov
45+ return true if xms_edov_result == :valid
46+
47+ # If we get here, verification failed - determine why
48+ error_key = determine_error_key ( xms_edov_result )
49+ error_message = build_error_message ( xms_edov_result )
4350
4451 # Use CallbackError to ensure the error is properly caught by the callback_phase
4552 # rescue clause and converted to an OmniAuth failure instead of bubbling up as a 500 error.
46- raise OmniAuth ::Strategies ::OAuth2 ::CallbackError . new (
47- :domain_verification_failed ,
48- verification_error_message
49- )
53+ raise OmniAuth ::Strategies ::OAuth2 ::CallbackError . new ( error_key , error_message )
5054 end
5155
5256 private
@@ -65,20 +69,81 @@ def verify!
6569 #
6670 # To get to it, we need to decode the ID token with the key material from Microsoft's
6771 # OIDC configuration endpoint, and inspect it for the claim in question.
68- def domain_verified_jwt_claim
72+ def check_xms_edov
6973 oidc_config = access_token . get ( OIDC_CONFIG_URL ) . parsed
7074 algorithms = oidc_config [ 'id_token_signing_alg_values_supported' ]
7175 jwks = get_jwks ( oidc_config )
7276 decoded_token = JWT . decode ( id_token , nil , true , algorithms : algorithms , jwks : jwks )
73- xms_edov_valid? ( decoded_token )
74- rescue JWT ::VerificationError , ::OAuth2 ::Error
75- false
77+
78+ xms_edov_value = decoded_token . first [ 'xms_edov' ]
79+
80+ if xms_edov_value . nil?
81+ :missing
82+ elsif [ '1' , 1 , 'true' , true ] . include? ( xms_edov_value )
83+ :valid
84+ else
85+ :false
86+ end
87+ rescue JWT ::VerificationError , ::OAuth2 ::Error => e
88+ :error
89+ end
90+
91+ def determine_error_key ( xms_edov_result )
92+ case xms_edov_result
93+ when :missing
94+ :domain_verification_xms_edov_missing
95+ when :false
96+ :domain_verification_xms_edov_false
97+ when :error
98+ :domain_verification_xms_edov_error
99+ else
100+ :domain_verification_failed
101+ end
76102 end
77103
78- def xms_edov_valid? ( decoded_token )
79- # https://github.com/MicrosoftDocs/azure-docs/issues/111425#issuecomment-1761043378
80- # Comments seemed to indicate the value is not consistent
81- [ '1' , 1 , 'true' , true ] . include? ( decoded_token . first [ 'xms_edov' ] )
104+ def build_error_message ( xms_edov_result )
105+ base_msg = "The email domain '#{ email_domain } ' does not match the principal domain '#{ upn_domain } '."
106+
107+ case xms_edov_result
108+ when :missing
109+ <<~MSG
110+ #{ base_msg }
111+
112+ The xms_edov claim is missing from the token, which could verify your email domain.
113+ Please ensure the xms_edov optional claim is configured in your Azure app registration.
114+
115+ You can either:
116+ * Configure the xms_edov optional claim in Azure (recommended)
117+ * Update the user's email to match the principal domain '#{ upn_domain } '
118+ * Skip verification on the '#{ email_domain } ' domain (not recommended)
119+ Refer to the README for more details.
120+ MSG
121+ when :false
122+ <<~MSG
123+ #{ base_msg }
124+
125+ The xms_edov claim indicates that '#{ email_domain } ' is NOT a verified domain in your Azure tenant.
126+
127+ You can either:
128+ * Add '#{ email_domain } ' as a verified custom domain in Azure Entra ID
129+ * Update the user's email to match the principal domain '#{ upn_domain } '
130+ * Skip verification on the '#{ email_domain } ' domain (not recommended)
131+ Refer to the README for more details.
132+ MSG
133+ when :error
134+ <<~MSG
135+ #{ base_msg }
136+
137+ Unable to verify the xms_edov claim (token validation error).
138+
139+ You can either:
140+ * Update the user's email to match the principal domain '#{ upn_domain } '
141+ * Skip verification on the '#{ email_domain } ' domain (not recommended)
142+ Refer to the README for more details.
143+ MSG
144+ else
145+ verification_error_message
146+ end
82147 end
83148
84149 def get_jwks ( oidc_config )
0 commit comments