1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| //------------------------------------------------------------------------------
function TSLTOAuth2AuthenticatorAzure.GetAuthCodeRequestURL(): string;
begin
with TSLTOAuth2AuthenticatorAzure.TURLBuilder.Create() do
try
AddParam('client_id', FOwner.ClientID);
if FOwner.ClientSecret <> '' then
AddParam('client_secret', FOwner.ClientSecret);
AddParam('response_type', 'code');
AddParam('redirect_uri', FOwner.Context.RedirectionEndpoint);
AddParam('scope', FOwner.Scope);
AddParam('response_mode', 'query');
if FOwner.Context.UserName <> '' then
AddParam('login_hint', FOwner.Context.UserName);
AddParam('prompt', 'consent');
Result := BuildURL(FAuthorizeEndpoint);
finally
Free();
end;
end;
//------------------------------------------------------------------------------
function TSLTOAuth2AuthenticatorAzure.Authenticate(): Boolean;
var
VClient: TRESTClient;
VRequest: TRESTRequest;
begin
// On vérifie les valeurs avant d'envoyer inutilement une requête
// En débogage, vous pouvez tenter de laisser les valeurs être envoyé dans l'état pour obtenir le message d'erreur Microsoft
// voir - https://docs.microsoft.com/fr-fr/azure/active-directory/develop/reference-aadsts-error-codes
// ClientID, GrantType & Scope also UserName/Password are required if ROPC
// ClientSecret are recommended but not required (only if defined in Portal Azure)
if FOwner.Tenant = '' then
raise ESLTOAuth2AuthenticatorError.Create('Tenant is required for use ' + ClassName());
if FOwner.ClientID = '' then
raise ESLTOAuth2AuthenticatorParamError.Create('ClientID is required for use ' + ClassName() + ' : See Error "AADSTS900144: The request body must contain the following parameter: ''client_id''."');
if FOwner.Scope = '' then
raise ESLTOAuth2AuthenticatorParamError.Create('Scope is required for use ' + ClassName() + ' : See Error "AADSTS900144: The request body must contain the following parameter: ''scope''."');
if not (FOwner.Context.FlowType in [oaftAuthorizationCode, oaftClientCredentials]) and not FOwner.Scope.Contains(TSLTOAuth2AuthenticatorAzure.SCOPE_AS_APPLICATION) then
if (FOwner.Context.UserName = '') or (FOwner.Context.Password = '') then
raise ESLTOAuth2AuthenticatorParamError.Create('UserName and Password has required for use ' + ClassName() + ' : See Error "AADSTS900144: The request body must contain the following parameter: ''username''." or "AADSTS900144: The request body must contain the following parameter: ''password''."');
VClient := TRESTClient.Create(FAccessTokenEndpoint);
try
VRequest := TRESTRequest.Create(VClient); // The Client owns the Request (will free it) and it will assign as Client property
VRequest.Method := TRESTRequestMethod.rmPOST;
VRequest.AddAuthParameter('client_id', FOwner.ClientID, TRESTRequestParameterKind.pkGETorPOST);
if FOwner.ClientSecret <> '' then
VRequest.AddAuthParameter('client_secret', FOwner.ClientSecret, TRESTRequestParameterKind.pkGETorPOST);
VRequest.AddAuthParameter('scope', FOwner.Scope, TRESTRequestParameterKind.pkGETorPOST);
if FOwner.Context.FlowType = oaftAuthorizationCode then
begin
VRequest.AddAuthParameter('grant_type', 'authorization_code', TRESTRequestParameterKind.pkGETorPOST);
VRequest.AddAuthParameter('code', FOwner.AuthorizationCode, TRESTRequestParameterKind.pkGETorPOST);
VRequest.AddAuthParameter('redirect_uri', FOwner.RedirectionEndpoint, TRESTRequestParameterKind.pkGETorPOST);
end
else if not FOwner.Scope.Contains(TSLTOAuth2AuthenticatorAzure.SCOPE_AS_APPLICATION) then
begin
VRequest.AddAuthParameter('grant_type', 'password', TRESTRequestParameterKind.pkGETorPOST);
VRequest.AddAuthParameter('username', FOwner.Context.UserName, TRESTRequestParameterKind.pkGETorPOST);
VRequest.AddAuthParameter('password', FOwner.Context.Password, TRESTRequestParameterKind.pkGETorPOST);
end
else
VRequest.AddAuthParameter('grant_type', 'client_credentials', TRESTRequestParameterKind.pkGETorPOST);
Result := FOwner.Execute(VRequest);
finally
VClient.Free();
end;
end; |
Partager