Skip to content

Commit

Permalink
[releases/24.0] Authentication failure when Get/Post request is sent …
Browse files Browse the repository at this point in the history
…to Azure Function multiple times with the same authentication parameters (#1828)

**Actions:**
Run the code below:
```
    local procedure SendRequestToAzureFunction()
    var
        AzureFunctionsAuthentication: Codeunit "Azure Functions Authentication";
        AzureFunctions: Codeunit "Azure Functions";
        AzureFunctionsAuth: Interface "Azure Functions Authentication";
        ClientID, Scope, AuthURL, EndpointText : Text;
        RequestBody: Text;
        Cert: SecretText;
        i: Integer;
    begin
        GetAuthParameters(ClientID, Cert, AuthURL, EndpointText);
        Scope := 'api://abcdefff-1111-2222-3333-123456789fff/.default';
        AzureFunctionsAuth := AzureFunctionsAuthentication.CreateOAuth2WithCert(EndpointText, '', ClientID, Cert, AuthURL, '', Scope);
        RequestBody := GetRequestBody();
        for i := 1 to 200 do
            AzureFunctions.SendPostRequest(AzureFunctionsAuth, RequestBody, 'application/json');
    end;
```

It sets Authentication parameters once and then sends POST request to
Azure Function 200 times.

**Expected result:**
Request is sent 200 times without errors.

**Actual result:**
After about 128 executions of AzureFunctions.SendPostRequest() the
function fails with the error "Authentication Failed".
The telemetry logs right befoge the authentication failure show the
error:

_Microsoft.Dynamics.Nav.LicensingService.Model.Exceptions.LicenseServiceTransientException
in AcquireApplicationTokenWithCertificate:
LicenseServiceTransientException: Exception details :
**RequestUriTooLong** - error returned._

The reason for this error is that every time the SendPostRequest is
invoked, the scope is added to the global list of scopes that is used to
authenticate in Azure Function. Therefore the list of scopes grows, and
it seems that the list is used to build URI for authentication, so after
multiple iterations the authentication function fails with
RequestUriTooLong.

Fixes
[AB#544604](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/544604)

Co-authored-by: Alexander Gladkov <[email protected]>
  • Loading branch information
AleksanderGladkov and Alexander Gladkov authored Aug 19, 2024
1 parent d3db218 commit e1382ed
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,10 @@ codeunit 7800 "Azure Functions Authentication"
procedure CreateOAuth2WithCert(Endpoint: Text; AuthenticationCode: Text; ClientId: Text; Cert: SecretText; OAuthAuthorityUrl: Text; RedirectURL: Text; Scope: Text): Interface "Azure Functions Authentication"
var
AzureFunctionsOAuth2Cert: Codeunit "Azure Functions OAuth2 Cert";
Scopes: List of [Text];
begin
AzureFunctionsOAuth2Cert.SetAuthParameters(Endpoint, AuthenticationCode, ClientId, Cert, OAuthAuthorityUrl, RedirectURL, Scope);
Scopes.Add(Scope);
AzureFunctionsOAuth2Cert.SetAuthParameters(Endpoint, AuthenticationCode, ClientId, Cert, OAuthAuthorityUrl, RedirectURL, Scopes);
exit(AzureFunctionsOAuth2Cert);
end;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ codeunit 7807 "Azure Functions OAuth2 Cert" implements "Azure Functions Authenti
[NonDebuggable]
AuthenticationCodeGlobal, EndpointGlobal : Text;
[NonDebuggable]
ClientIdGlobal, OAuthAuthorityUrlGlobal, RedirectURLGlobal, ScopeGlobal : Text;
ClientIdGlobal, OAuthAuthorityUrlGlobal, RedirectURLGlobal : Text;
CertGlobal: SecretText;
AccessToken: SecretText;
Scopes: List of [Text];
ScopesGlobal: List of [Text];
BearerLbl: Label 'Bearer %1', Locked = true;
FailedToGetTokenErr: Label 'Authorization failed to Azure function: %1', Locked = true;
AzureFunctionCategoryLbl: Label 'Connect to Azure Functions', Locked = true;
Expand All @@ -38,9 +38,8 @@ codeunit 7807 "Azure Functions OAuth2 Cert" implements "Azure Functions Authenti
IdToken: Text;
begin
UriBuilder.Init(EndpointGlobal);
Scopes.Add(ScopeGlobal);

OAuth2.AcquireTokensWithCertificate(ClientIdGlobal, CertGlobal, RedirectURLGlobal, OAuthAuthorityUrlGlobal, Scopes, AccessToken, IdToken);
OAuth2.AcquireTokensWithCertificate(ClientIdGlobal, CertGlobal, RedirectURLGlobal, OAuthAuthorityUrlGlobal, ScopesGlobal, AccessToken, IdToken);

if AccessToken.IsEmpty() then begin
UriBuilder.GetUri(Uri);
Expand All @@ -62,14 +61,14 @@ codeunit 7807 "Azure Functions OAuth2 Cert" implements "Azure Functions Authenti
end;

[NonDebuggable]
procedure SetAuthParameters(Endpoint: Text; AuthenticationCode: Text; ClientId: Text; Cert: SecretText; OAuthAuthorityUrl: Text; RedirectURL: Text; Scope: Text)
procedure SetAuthParameters(Endpoint: Text; AuthenticationCode: Text; ClientId: Text; Cert: SecretText; OAuthAuthorityUrl: Text; RedirectURL: Text; Scopes: List of [Text])
begin
EndpointGlobal := Endpoint;
AuthenticationCodeGlobal := AuthenticationCode;
ClientIdGlobal := ClientId;
CertGlobal := Cert;
OAuthAuthorityUrlGlobal := OAuthAuthorityUrl;
RedirectURLGlobal := RedirectURL;
ScopeGlobal := Scope;
ScopesGlobal := Scopes;
end;
}

0 comments on commit e1382ed

Please sign in to comment.