@@ -56,6 +56,7 @@ def __init__(
56
56
self , authority_url , http_client ,
57
57
validate_authority = True ,
58
58
instance_discovery = None ,
59
+ oidc_authority_url = None ,
59
60
):
60
61
"""Creates an authority instance, and also validates it.
61
62
@@ -65,12 +66,56 @@ def __init__(
65
66
This parameter only controls whether an instance discovery will be
66
67
performed.
67
68
"""
69
+ self ._http_client = http_client
70
+ if oidc_authority_url :
71
+ logger .info ("Initializing with OIDC authority: %s" , oidc_authority_url )
72
+ tenant_discovery_endpoint = self ._initialize_oidc_authority (
73
+ oidc_authority_url )
74
+ else :
75
+ logger .info ("Initializing with Entra authority: %s" , authority_url )
76
+ tenant_discovery_endpoint = self ._initialize_entra_authority (
77
+ authority_url , validate_authority , instance_discovery )
78
+ try :
79
+ openid_config = tenant_discovery (
80
+ tenant_discovery_endpoint ,
81
+ self ._http_client )
82
+ except ValueError :
83
+ error_message = (
84
+ "Unable to get OIDC authority configuration for {url} "
85
+ "because its OIDC Discovery endpoint is unavailable at "
86
+ "{url}/.well-known/openid-configuration " .format (url = oidc_authority_url )
87
+ if oidc_authority_url else
88
+ "Unable to get authority configuration for {}. "
89
+ "Authority would typically be in a format of "
90
+ "https://login.microsoftonline.com/your_tenant "
91
+ "or https://tenant_name.ciamlogin.com "
92
+ "or https://tenant_name.b2clogin.com/tenant.onmicrosoft.com/policy. "
93
+ .format (authority_url )
94
+ ) + " Also please double check your tenant name or GUID is correct."
95
+ raise ValueError (error_message )
96
+ logger .debug (
97
+ 'openid_config("%s") = %s' , tenant_discovery_endpoint , openid_config )
98
+ self .authorization_endpoint = openid_config ['authorization_endpoint' ]
99
+ self .token_endpoint = openid_config ['token_endpoint' ]
100
+ self .device_authorization_endpoint = openid_config .get ('device_authorization_endpoint' )
101
+ _ , _ , self .tenant = canonicalize (self .token_endpoint ) # Usually a GUID
102
+
103
+ def _initialize_oidc_authority (self , oidc_authority_url ):
104
+ authority , self .instance , tenant = canonicalize (oidc_authority_url )
105
+ self .is_adfs = tenant .lower () == 'adfs' # As a convention
106
+ self ._is_b2c = True # Not exactly true, but
107
+ # OIDC Authority was designed for CIAM which is the next gen of B2C.
108
+ # Besides, application.py uses this to bypass broker.
109
+ self ._is_known_to_developer = True # Not really relevant, but application.py uses this to bypass authority validation
110
+ return oidc_authority_url + "/.well-known/openid-configuration"
111
+
112
+ def _initialize_entra_authority (
113
+ self , authority_url , validate_authority , instance_discovery ):
68
114
# :param instance_discovery:
69
115
# By default, the known-to-Microsoft validation will use an
70
116
# instance discovery endpoint located at ``login.microsoftonline.com``.
71
117
# You can customize the endpoint by providing a url as a string.
72
118
# Or you can turn this behavior off by passing in a False here.
73
- self ._http_client = http_client
74
119
if isinstance (authority_url , AuthorityBuilder ):
75
120
authority_url = str (authority_url )
76
121
authority , self .instance , tenant = canonicalize (authority_url )
@@ -111,24 +156,7 @@ def __init__(
111
156
version = "" if self .is_adfs else "/v2.0" ,
112
157
)
113
158
).geturl () # Keeping original port and query. Query is useful for test.
114
- try :
115
- openid_config = tenant_discovery (
116
- tenant_discovery_endpoint ,
117
- self ._http_client )
118
- except ValueError :
119
- raise ValueError (
120
- "Unable to get authority configuration for {}. "
121
- "Authority would typically be in a format of "
122
- "https://login.microsoftonline.com/your_tenant "
123
- "or https://tenant_name.ciamlogin.com "
124
- "or https://tenant_name.b2clogin.com/tenant.onmicrosoft.com/policy. "
125
- "Also please double check your tenant name or GUID is correct." .format (
126
- authority_url ))
127
- logger .debug ("openid_config = %s" , openid_config )
128
- self .authorization_endpoint = openid_config ['authorization_endpoint' ]
129
- self .token_endpoint = openid_config ['token_endpoint' ]
130
- self .device_authorization_endpoint = openid_config .get ('device_authorization_endpoint' )
131
- _ , _ , self .tenant = canonicalize (self .token_endpoint ) # Usually a GUID
159
+ return tenant_discovery_endpoint
132
160
133
161
def user_realm_discovery (self , username , correlation_id = None , response = None ):
134
162
# It will typically return a dict containing "ver", "account_type",
0 commit comments