Skip to content

Commit

Permalink
[24.x] azure function support cert auth (#1151)
Browse files Browse the repository at this point in the history
#### Summary <!-- Provide a general summary of your changes -->

Port down from #1120

#### Work Item(s) <!-- Add the issue number here after the #. The issue
needs to be open and approved. Submitting PRs with no linked issues or
unapproved issues is highly discouraged. -->
Fixes
[AB#535802](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/535802)

---------

Co-authored-by: waabsuea <[email protected]>
Co-authored-by: Wael <[email protected]>
  • Loading branch information
3 people authored May 21, 2024
1 parent a1fe655 commit 9dbc72c
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,23 @@ codeunit 7800 "Azure Functions Authentication"
exit(AzureFunctionsCodeAuth);
end;

/// <summary>
/// Creates an instance of OAuth2 authentication with certificate of Azure function interface.
/// </summary>
/// <param name="Endpoint">Azure function endpoint</param>
/// <param name="AuthenticationCode">Azure function authentication code, empty if anonymous.</param>
/// <param name="ClientId">The Application (client) ID that the Azure portal – App registrations experience assigned to your app.</param>
/// <param name="Cert">The Application (client) certificate configured in the Azure Portal.</param>
/// <param name="OAuthAuthorityUrl">The identity authorization provider URL.</param>
/// <param name="RedirectURL">The redirectURL of your app, for azure function this could be empty</param>
/// <param name="Scope">The scope for the token, example: "api://(app id)/.default"</param>
/// <returns>Instance of Azure function response object.</returns>
[NonDebuggable]
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";
begin
AzureFunctionsOAuth2Cert.SetAuthParameters(Endpoint, AuthenticationCode, ClientId, Cert, OAuthAuthorityUrl, RedirectURL, Scope);
exit(AzureFunctionsOAuth2Cert);
end;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------

namespace System.Azure.Functions;

using System.Utilities;
using System.Security.Authentication;
using System.Telemetry;

codeunit 7807 "Azure Functions OAuth2 Cert" implements "Azure Functions Authentication"
{
Access = Internal;
InherentEntitlements = X;
InherentPermissions = X;

var
[NonDebuggable]
AuthenticationCodeGlobal, EndpointGlobal : Text;
[NonDebuggable]
ClientIdGlobal, OAuthAuthorityUrlGlobal, RedirectURLGlobal, ScopeGlobal : Text;
CertGlobal: SecretText;
AccessToken: SecretText;
Scopes: 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;

procedure Authenticate(var RequestMessage: HttpRequestMessage): Boolean
var
Uri: Codeunit Uri;
OAuth2: Codeunit OAuth2;
UriBuilder: Codeunit "Uri Builder";
FeatureTelemetry: Codeunit "Feature Telemetry";
Headers: HttpHeaders;
Dimensions: Dictionary of [Text, Text];
IdToken: Text;
begin
UriBuilder.Init(EndpointGlobal);
Scopes.Add(ScopeGlobal);

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

if AccessToken.IsEmpty() then begin
UriBuilder.GetUri(Uri);
Dimensions.Add('FunctionHost', Format(Uri.GetHost()));
FeatureTelemetry.LogError('0000I75', AzureFunctionCategoryLbl, 'Acquiring token', StrSubstNo(FailedToGetTokenErr, Uri.GetHost()), '', Dimensions);
exit(false);
end;

RequestMessage.GetHeaders(Headers);
Headers.Remove('Authorization');
Headers.Add('Authorization', SecretStrSubstNo(BearerLbl, AccessToken));

if AuthenticationCodeGlobal <> '' then
UriBuilder.AddQueryParameter('Code', AuthenticationCodeGlobal);

UriBuilder.GetUri(Uri);
RequestMessage.SetRequestUri(Uri.GetAbsoluteUri());
exit(true);
end;

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

0 comments on commit 9dbc72c

Please sign in to comment.