Skip to content

Commit

Permalink
Fixes certificate based authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
maben-mw committed Apr 11, 2023
1 parent 4edbcdd commit b97baab
Show file tree
Hide file tree
Showing 14 changed files with 2,362 additions and 2,175 deletions.
4,379 changes: 2,215 additions & 2,164 deletions Documentation/APIReference.md

Large diffs are not rendered by default.

13 changes: 8 additions & 5 deletions Documentation/Testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ features like proxy settings.
### `Common` Azure App Registration

Configure an Azure App for which a Client Secret has been generated as the
`Storage` App Registration. And if also running the interactive authentication
tests make sure that for this App:
Configure an Azure App for which a Client Secret has been generated and a
Client Certificate has been registered. Ensure this App's service principal
is granted access to the storage account used for testing, see also
[Storage Account](#storage-account) below. And if also running the
interactive authentication tests make sure that for this App:

* A Redirect Uri has been configured in the form of `http://localhost:PORT`
where *PORT* is configurable.
Expand Down Expand Up @@ -92,7 +94,7 @@ which:

* A Client Secret has been generated.

### `Storage` Storage Account
### Storage Account

The storage account should contain three containers:

Expand Down Expand Up @@ -134,6 +136,7 @@ Once generated note down the "Connection string" and "SAS token".
| `STORAGE_ACCOUNT_NAME` | Name of the storage account |
| `AZURE_CLIENT_ID` | Client ID of the Azure App |
| `AZURE_CLIENT_SECRET` | Client Secret which has been generated for the App |
| `AZURE_CLIENT_CERTIFICATE` | Base64 encoded PEM-format certificate as registered for the App |
| `AZURE_TENANT_ID` | Azure Tenant ID |

## `/KeyVault` Azure Key Vault unit tests
Expand Down Expand Up @@ -174,4 +177,4 @@ A Key Vault account needs to exist:
| `KEYVAULT_TENANT_ID` | Azure Tenant ID |
| `KEYVAULT_VAULT_NAME` | Name of the Key Vault |

[//]: # (Copyright 2021-2022 The MathWorks, Inc.)
[//]: # (Copyright 2021-2023 The MathWorks, Inc.)
4 changes: 4 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Release Notes

## Release 0.3.1 April 11th 2023

* Fixes issue with client certificate authentication

## Release 0.3.0 March 27th 2023

* Added EndPoint setting support
Expand Down
6 changes: 5 additions & 1 deletion Software/MATLAB/app/functions/configureCredentials.m
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,14 @@
write(logObj,'error',['pem certificate file not found: ', strrep(char(settings.PemCertificate),'\','\\')]);
else
usePemfile = true;
builder = azure.identity.ClientCertificateCredentialBuilder();
end
else
write(logObj,'error','PemCertificate may not be set to an empty string');
end
else
builder = azure.identity.ClientSecretCredentialBuilder();
end
builder = azure.identity.ClientSecretCredentialBuilder();
builder = builder.clientId(settings.ClientId);
builder = builder.tenantId(settings.TenantId);
% If a pem file is configured and exists use it else default to the client secret
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
classdef ClientCertificateCredential < azure.core.credential.TokenCredential
% CLIENTCERTIFICATECREDENTIAL AAD credential acquires a token with a client certificate

% Copyright 2023 The MathWorks, Inc.

properties
end

methods
function obj = ClientCertificateCredential(clientCertificateCredentialj)
% Created using a ClientCertificateCredential java object from the
% ClientCertificateCredentialBuilder class only
if isa(clientCertificateCredentialj, 'com.azure.identity.ClientCertificateCredential')
obj.Handle = clientCertificateCredentialj;
else
logObj = Logger.getLogger();
write(logObj,'error','Expected argument of type com.azure.identity.ClientCertificateCredential');
end
end
end

end
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
classdef ClientCertificateCredentialBuilder < azure.identity.CredentialBuilderBase
% CLIENTCERTIFICATECREDENTIALBUILDER Builder for ClientCertificateCredential

% Copyright 2023 The MathWorks, Inc.

properties
end

methods

function obj = ClientCertificateCredentialBuilder(varargin)

initialize('loggerPrefix', 'Azure:Common');
if nargin == 0
obj.Handle = com.azure.identity.ClientCertificateCredentialBuilder();
elseif nargin == 1 && isa(varargin{1}, 'com.azure.identity.ClientCertificateCredentialBuilder')
obj.Handle = varargin{1};
else
logObj = Logger.getLogger();
write(logObj,'error','Invalid argument(s)');
end

end %function

end %methods
end %class
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
function clientCertificateCredentialBuilder = authorityHost(obj, authorityHost)
% AUTHORITYHOST Specifies the Azure Active Directory endpoint to acquire tokens
% An updated ClientCertificateCredentialBuilder is returned.

% Copyright 2023 The MathWorks, Inc.

if ~(ischar(authorityHost) || isStringScalar(authorityHost))
logObj = Logger.getLogger();
write(logObj,'error','Expected argument of type character vector or scalar string');
end

clientCertificateCredentialBuilderj = obj.Handle.authorityHost(authorityHost);
clientCertificateCredentialBuilder = azure.identity.ClientCertificateCredentialBuilder(clientCertificateCredentialBuilderj);

end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
function clientCertificateCredential = build(obj)
% BUILD Creates new ClientCertificateCredential with the configured options set

% Copyright 2023 The MathWorks, Inc.

clientCertificateCredentialj = obj.Handle.build();
clientCertificateCredential = azure.identity.ClientCertificateCredential(clientCertificateCredentialj);

end
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
function clientCertificateCredentialBuilder = clientId(obj, clientId)
% CLIENTID Sets client id
% An updated ClientCertificateCredentialBuilder is returned.

% Copyright 2020 The MathWorks, Inc.

if ~(ischar(clientId) || isStringScalar(clientId))
logObj = Logger.getLogger();
write(logObj,'error','Expected argument of type character vector or scalar string');
end

clientCertificateCredentialBuilderj = obj.Handle.clientId(clientId);
clientCertificateCredentialBuilder = azure.identity.ClientCertificateCredentialBuilder(clientCertificateCredentialBuilderj);

end
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function clientSecretCredentialBuilder = pemCertificate(obj, certificatePath)
function clientCertificateCredentialBuilder = pemCertificate(obj, certificatePath)
% PEMCERTIFICATE Sets the path of the PEM certificate for authenticating to AAD
% An updated ClientSecretCredentialBuilder is returned.
% An updated ClientCertificateCredentialBuilder is returned.

% Copyright 2020 The MathWorks, Inc.

Expand All @@ -14,7 +14,7 @@
write(logObj,'error',['File not found: ', strrep(char(certificatePath),'\','\\')]);
end

clientSecretCredentialBuilderj = obj.Handle.pemCertificate(certificatePath);
clientSecretCredentialBuilder = azure.identity.ClientSecretCredentialBuilder(clientSecretCredentialBuilderj);
clientCertificateCredentialBuilderj = obj.Handle.pemCertificate(certificatePath);
clientCertificateCredentialBuilder = azure.identity.ClientCertificateCredentialBuilder(clientCertificateCredentialBuilderj);

end
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
function clientCertificateCredentialBuilder = tenantId(obj, tenantId)
% TENANTID Sets tenant id to authenticate through ClientCertificateCredential
% An updated ClientCertificateCredentialBuilder is returned.

% Copyright 2023 The MathWorks, Inc.

if ~(ischar(tenantId) || isStringScalar(tenantId))
logObj = Logger.getLogger();
write(logObj,'error','Expected argument of type character vector or scalar string');
end

clientCertificateCredentialBuilderj = obj.Handle.tenantId(tenantId);
clientCertificateCredentialBuilder = azure.identity.ClientCertificateCredentialBuilder(clientCertificateCredentialBuilderj);

end
13 changes: 13 additions & 0 deletions Software/MATLAB/test/unit/Common/commonFixture.m
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,18 @@ function setup(~)
));
f = fopen(configFile,'w'); fwrite(f,json);fclose(f);

configFile = fullfile(AzureCommonRoot, 'config', 'test_ClientCertificate.json');
certFile = fullfile(AzureCommonRoot, 'config', 'test_cert.pem');
json = jsonencode(struct(...
'AuthMethod','ClientSecret',...
'TenantId',getenv('AZURE_TENANT_ID'),...
'ClientId',getenv('AZURE_CLIENT_ID'),...
'PemCertificate',certFile,...
'AccountName',getenv('STORAGE_ACCOUNT_NAME')...
));
f = fopen(configFile,'w'); fwrite(f,json);fclose(f);
f = fopen(certFile,'w'); fwrite(f,matlab.net.base64decode(getenv('AZURE_CLIENT_CERTIFICATE')));fclose(f);

configFile = fullfile(AzureCommonRoot, 'config', 'test_DeviceCode.json');
json = jsonencode(struct(...
'AuthMethod','DeviceCode',...
Expand All @@ -79,6 +91,7 @@ function setup(~)
function teardown(~)
disp 'Removing Configuration Files'
delete(fullfile(AzureCommonRoot,'config','test_*.json'))
delete(fullfile(AzureCommonRoot,'config','test_cert.pem'))
end
end
end
10 changes: 10 additions & 0 deletions Software/MATLAB/test/unit/Common/testCredentials.m
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,16 @@ function testBuilderClientSecret(testCase,Client)
testCase.interactWithClient(Client,credentials,configFile);
end

function testBuilderClientCertificate(testCase,Client)
disp('Running testBuilderClientCertificate');
configFile = fullfile(AzureCommonRoot, 'config', 'test_ClientCertificate.json');
% Configure ClientSecret credentials
credentials = configureCredentials(configFile);
testCase.verifyClass(credentials, 'azure.identity.ClientCertificateCredential');

testCase.interactWithClient(Client,credentials,configFile);
end


function testBuilderInteractiveBrowser(testCase,Client)
disp('Running testBuilderInteractiveBrowser');
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.3.0
0.3.1

0 comments on commit b97baab

Please sign in to comment.