Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[24.x] azure function support cert auth #1151

Merged
merged 4 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}
Loading