From 755261ec2d94cab6820437d0d68dc683980f482b Mon Sep 17 00:00:00 2001 From: cormacpayne Date: Mon, 24 Sep 2018 11:29:22 -0700 Subject: [PATCH 1/2] Test certificate authentication --- .../Cmdlets/ConnectAccount.cs | 16 ++++++++++++++++ src/Authentication.Test/LoginTests.cs | 16 ++++++++++++++++ .../Authentication/AdalTokenProvider.cs | 15 +++++++++++++++ .../Authentication/ITokenProvider.cs | 4 +--- .../Authentication/UserTokenProvider.Netcore.cs | 9 +++++++-- .../Factories/AuthenticationFactory.cs | 4 ---- src/Dependencies.Test.Netcore.targets | 2 +- 7 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/Authentication.Test/Cmdlets/ConnectAccount.cs b/src/Authentication.Test/Cmdlets/ConnectAccount.cs index cf13a42472..99a4988a77 100644 --- a/src/Authentication.Test/Cmdlets/ConnectAccount.cs +++ b/src/Authentication.Test/Cmdlets/ConnectAccount.cs @@ -58,6 +58,12 @@ public class ConnectAccount : AzureRMCmdlet [Parameter(Mandatory = false)] public string Password { get; set; } + [Parameter(Mandatory = false)] + public string ApplicationId { get; set; } + + [Parameter(Mandatory = false)] + public string CertificateThumbprint { get; set; } + protected override void BeginProcessing() { _profile = new AzureRmAutosaveProfile( @@ -89,6 +95,16 @@ public override void ExecuteCmdlet() password = _credential.Password; } + if (!string.IsNullOrEmpty(ApplicationId)) + { + Account.Id = ApplicationId; + } + + if (!string.IsNullOrEmpty(CertificateThumbprint)) + { + Account.SetThumbprint(CertificateThumbprint); + } + if (!string.IsNullOrEmpty(TenantId)) { Account.SetProperty(AzureAccount.Property.Tenants, new[] { TenantId }); diff --git a/src/Authentication.Test/LoginTests.cs b/src/Authentication.Test/LoginTests.cs index d75466129f..5d75888d79 100644 --- a/src/Authentication.Test/LoginTests.cs +++ b/src/Authentication.Test/LoginTests.cs @@ -47,6 +47,8 @@ public class LoginTests private string _subscriptionName = null; private string _userName = null; private string _password = null; + private string _applicationId = null; + private string _certificateThumbprint = null; public LoginTests() { @@ -65,6 +67,8 @@ public LoginTests() _cmdlet.SubscriptionName = _subscriptionName; _cmdlet.UserName = _userName; _cmdlet.Password = _password; + _cmdlet.ApplicationId = _applicationId; + _cmdlet.CertificateThumbprint = _certificateThumbprint; _cmdlet.CommandRuntime = new MockCommandRuntime(); } @@ -96,6 +100,18 @@ public void LoginWithServicePrincipal() Login(); } + [Fact] + [Trait(Category.AcceptanceType, Category.LiveOnly)] + public void LoginWithCertificate() + { + // REQUIRED: + // _tenantId --> Id of the tenant that the service principal is registered to + // _applicationId --> Application id of the service principal + // _certificateThumbprint --> Thumbprint of the certificate used to authenticate the service principal + _account = new AzureAccount() { Type = AzureAccount.AccountType.ServicePrincipal }; + Login(); + } + private void EnableAutosave(IAzureSession session, bool writeAutoSaveFile, out ContextAutosaveSettings result) { var store = session.DataStore; diff --git a/src/Authentication/Authentication/AdalTokenProvider.cs b/src/Authentication/Authentication/AdalTokenProvider.cs index ad4a56cd3c..48895ef36e 100644 --- a/src/Authentication/Authentication/AdalTokenProvider.cs +++ b/src/Authentication/Authentication/AdalTokenProvider.cs @@ -126,6 +126,21 @@ public IAccessToken GetAccessToken( throw new ArgumentException(Resources.UnsupportedCredentialType, "credentialType"); } } + + public IAccessToken GetAccessTokenWithCertificate( + AdalConfiguration config, + string clientId, + string certificate, + string credentialType) + { + switch (credentialType) + { + case AzureAccount.AccountType.ServicePrincipal: + return servicePrincipalTokenProvider.GetAccessTokenWithCertificate(config, clientId, certificate, credentialType); + default: + throw new ArgumentException(string.Format(Resources.UnsupportedCredentialType, credentialType), "credentialType"); + } + } #endif } diff --git a/src/Authentication/Authentication/ITokenProvider.cs b/src/Authentication/Authentication/ITokenProvider.cs index 9994d7a61c..402612ed9f 100644 --- a/src/Authentication/Authentication/ITokenProvider.cs +++ b/src/Authentication/Authentication/ITokenProvider.cs @@ -42,8 +42,7 @@ IAccessToken GetAccessToken( string userId, SecureString password, string credentialType); - -#if !NETSTANDARD + /// /// Get a new authentication token for the given environment /// @@ -57,6 +56,5 @@ IAccessToken GetAccessTokenWithCertificate( string principalId, string certificateThumbprint, string credentialType); -#endif } } diff --git a/src/Authentication/Authentication/UserTokenProvider.Netcore.cs b/src/Authentication/Authentication/UserTokenProvider.Netcore.cs index 108a7dbf10..23a06dae9f 100644 --- a/src/Authentication/Authentication/UserTokenProvider.Netcore.cs +++ b/src/Authentication/Authentication/UserTokenProvider.Netcore.cs @@ -106,13 +106,13 @@ private void Renew(AdalAccessToken token) private AuthenticationContext CreateContext(AdalConfiguration config) { - return new AuthenticationContext(config.AdEndpoint + config.AdDomain, + return new AuthenticationContext(config.AdEndpoint + config.AdDomain, config.ValidateAuthority, config.TokenCache); } // We have to run this in a separate thread to guarantee that it's STA. This method // handles the threading details. - private AuthenticationResult AcquireToken(AdalConfiguration config, Action promptAction, + private AuthenticationResult AcquireToken(AdalConfiguration config, Action promptAction, string userId, SecureString password, bool renew = false) { AuthenticationResult result = null; @@ -237,6 +237,11 @@ private string GetExceptionMessage(Exception ex) return message; } + public IAccessToken GetAccessTokenWithCertificate(AdalConfiguration config, string principalId, string certificateThumbprint, string credentialType) + { + throw new NotImplementedException(); + } + /// /// Implementation of using data from ADAL /// diff --git a/src/Authentication/Factories/AuthenticationFactory.cs b/src/Authentication/Factories/AuthenticationFactory.cs index 3175f9b18b..770ad7ed11 100644 --- a/src/Authentication/Factories/AuthenticationFactory.cs +++ b/src/Authentication/Factories/AuthenticationFactory.cs @@ -136,11 +136,7 @@ public IAccessToken Authenticate( else if (account.IsPropertySet(AzureAccount.Property.CertificateThumbprint)) { var thumbprint = account.GetProperty(AzureAccount.Property.CertificateThumbprint); -#if !NETSTANDARD token = TokenProvider.GetAccessTokenWithCertificate(configuration, account.Id, thumbprint, account.Type); -#else - throw new NotSupportedException("Certificate based authentication is not supported in netcore version."); -#endif } else { diff --git a/src/Dependencies.Test.Netcore.targets b/src/Dependencies.Test.Netcore.targets index 621267b299..4d29dd53fd 100644 --- a/src/Dependencies.Test.Netcore.targets +++ b/src/Dependencies.Test.Netcore.targets @@ -13,7 +13,7 @@ - + From e9656fe324a597d8fc28c98e41ce604bd17f7ae3 Mon Sep 17 00:00:00 2001 From: cormacpayne Date: Tue, 16 Oct 2018 13:56:16 -0700 Subject: [PATCH 2/2] Revert change to Newtonsoft.Json version --- src/Dependencies.Test.Netcore.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Dependencies.Test.Netcore.targets b/src/Dependencies.Test.Netcore.targets index f5d2cf63d4..f81f0a5491 100644 --- a/src/Dependencies.Test.Netcore.targets +++ b/src/Dependencies.Test.Netcore.targets @@ -13,7 +13,7 @@ - +