1- from . import oauth2
1+ from .oauth2 import Client
22from .authority import Authority
33from .request import decorate_scope
4- from .client_credential import ClientCredentialRequest
4+ from .assertion import create_jwt_assertion
55
66
77class ClientApplication (object ):
88
99 def __init__ (
1010 self , client_id ,
11- authority_url = "https://login.microsoftonline.com/common/" ,
11+ authority = "https://login.microsoftonline.com/common/" ,
1212 validate_authority = True ):
1313 self .client_id = client_id
14- self .authority = Authority (authority_url , validate_authority )
14+ self .authority = Authority (authority , validate_authority )
15+ # Here the self.authority is not the same type as authority in input
16+
17+ @staticmethod
18+ def _build_auth_parameters (client_credential , token_endpoint , client_id ):
19+ if isinstance (client_credential , dict ):
20+ type_ = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'
21+ assertion = create_jwt_assertion (
22+ client_credential ['certificate' ],
23+ client_credential ['thumbprint' ],
24+ audience = token_endpoint , issuer = client_id )
25+ return {
26+ 'client_assertion_type' : type_ , 'client_assertion' : assertion }
27+ else :
28+ return {'client_secret' : client_credential }
1529
1630 def acquire_token_silent (
1731 self , scope ,
@@ -20,14 +34,17 @@ def acquire_token_silent(
2034 policy = '' ,
2135 force_refresh = False , # To force refresh an Access Token (not a RT)
2236 ** kwargs ):
23- a = Authority (authority ) if authority else self .authority
24- client = oauth2 .Client (self .client_id , token_endpoint = a .token_endpoint )
37+ the_authority = Authority (authority ) if authority else self .authority
2538 refresh_token = kwargs .get ('refresh_token' ) # For testing purpose
26- response = client .get_token_by_refresh_token (
27- refresh_token ,
28- scope = decorate_scope (scope , self .client_id , policy ),
29- client_secret = getattr (self , 'client_credential' ), # TODO: JWT too
30- query = {'policy' : policy } if policy else None )
39+ response = Client (
40+ self .client_id , token_endpoint = the_authority .token_endpoint ,
41+ default_body = self ._build_auth_parameters (
42+ self .client_credential ,
43+ the_authority .token_endpoint , self .client_id )
44+ ).acquire_token_with_refresh_token (
45+ refresh_token ,
46+ scope = decorate_scope (scope , self .client_id , policy ),
47+ query = {'p' : policy } if policy else None )
3148 # TODO: refresh the refresh_token
3249 return response
3350
@@ -79,11 +96,15 @@ def __init__(
7996 self .user_token_cache = user_token_cache
8097 self .app_token_cache = None # TODO
8198
82- def acquire_token_for_client (self , scope , policy = '' ):
83- return ClientCredentialRequest (
84- client_id = self .client_id , client_credential = self .client_credential ,
85- scope = scope , # This grant flow requires no scope decoration
86- policy = policy , authority = self .authority ).run ()
99+ def acquire_token_for_client (self , scope , policy = None ):
100+ token_endpoint = self .authority .token_endpoint
101+ return Client (
102+ self .client_id , token_endpoint = token_endpoint ,
103+ default_body = self ._build_auth_parameters (
104+ self .client_credential , token_endpoint , self .client_id )
105+ ).acquire_token_with_client_credentials (
106+ scope = scope , # This grant flow requires no scope decoration
107+ query = {'p' : policy } if policy else None )
87108
88109 def get_authorization_request_url (
89110 self ,
@@ -109,16 +130,18 @@ def get_authorization_request_url(
109130 sending them on the wire.)
110131 :param str state: Recommended by OAuth2 for CSRF protection.
111132 """
112- a = Authority (authority ) if authority else self .authority
113- grant = oauth2 .AuthorizationCodeGrant (
114- self .client_id , authorization_endpoint = a .authorization_endpoint )
115- return grant .authorization_url (
133+ the_authority = Authority (authority ) if authority else self .authority
134+ client = Client (
135+ self .client_id ,
136+ authorization_endpoint = the_authority .authorization_endpoint )
137+ return client .authorization_url (
138+ response_type = "code" , # Using Authorization Code grant
116139 redirect_uri = redirect_uri , state = state , login_hint = login_hint ,
117140 scope = decorate_scope (scope , self .client_id , policy ),
118141 policy = policy if policy else None ,
119142 ** (extra_query_params or {}))
120143
121- def acquire_token_by_authorization_code (
144+ def acquire_token_with_authorization_code (
122145 self ,
123146 code ,
124147 scope , # Syntactically required. STS accepts empty value though.
@@ -151,13 +174,15 @@ def acquire_token_by_authorization_code(
151174 # So in theory, you can omit scope here when you were working with only
152175 # one scope. But, MSAL decorates your scope anyway, so they are never
153176 # really empty.
154- grant = oauth2 .AuthorizationCodeGrant (
155- self .client_id , token_endpoint = self .authority .token_endpoint )
156- return grant .get_token (
157- code , redirect_uri = redirect_uri ,
158- scope = decorate_scope (scope , self .client_id , policy ),
159- client_secret = self .client_credential , # TODO: Support certificate
160- query = {'policy' : policy } if policy else None )
177+ return Client (
178+ self .client_id , token_endpoint = self .authority .token_endpoint ,
179+ default_body = self ._build_auth_parameters (
180+ self .client_credential ,
181+ self .authority .token_endpoint , self .client_id )
182+ ).acquire_token_with_authorization_code (
183+ code , redirect_uri = redirect_uri ,
184+ scope = decorate_scope (scope , self .client_id , policy ),
185+ query = {'p' : policy } if policy else None )
161186
162187 def acquire_token_on_behalf_of (
163188 self , user_assertion , scope , authority = None , policy = '' ):
0 commit comments