Skip to content

Commit 497a8de

Browse files
authored
Merge pull request Azure#4389 from liangyong79/preview
Add-AzureAnalysisServicesAccount to support login with Service Principal
2 parents e9a4cb3 + b1345f2 commit 497a8de

File tree

7 files changed

+287
-17
lines changed

7 files changed

+287
-17
lines changed

src/ResourceManager/AnalysisServices/ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
- Enable to set/disable backup blob container for backup/restore Azure Analysis Services Server
2525
* Updated Sku lookup in New-AzureRmAnalysisServicesServer and Set-AzureRmAnalysisServicesServer
2626
- Changed hard coded Sku into dynamic lookup.
27+
* Add-AzureAnalysisServicesAccount to support login with Service Principal
2728

2829
## Version 0.4.2
2930

src/ResourceManager/AnalysisServices/Commands.AnalysisServices.Dataplane/Commands/AddAzureASAccount.cs

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,54 @@ namespace Microsoft.Azure.Commands.AnalysisServices.Dataplane
2828
/// <summary>
2929
/// Cmdlet to log into an Analysis Services environment
3030
/// </summary>
31-
[Cmdlet("Add", "AzureAnalysisServicesAccount", SupportsShouldProcess=true)]
31+
[Cmdlet("Add", "AzureAnalysisServicesAccount", DefaultParameterSetName = "UserParameterSetName", SupportsShouldProcess =true)]
3232
[Alias("Login-AzureAsAccount")]
3333
[OutputType(typeof(AsAzureProfile))]
3434
public class AddAzureASAccountCommand : AzurePSCmdlet, IModuleAssemblyInitializer
3535
{
36-
[Parameter(Position = 0, Mandatory = false, HelpMessage = "Name of the Azure Analysis Services environment to which to logon to")]
36+
private const string UserParameterSet = "UserParameterSetName";
37+
private const string ServicePrincipalWithPasswordParameterSet = "ServicePrincipalWithPasswordParameterSetName";
38+
private const string ServicePrincipalWithCertificateParameterSet = "ServicePrincipalWithCertificateParameterSetName";
39+
40+
[Parameter(ParameterSetName = UserParameterSet,
41+
Mandatory = false, HelpMessage = "Name of the Azure Analysis Services environment to which to logon to", Position = 0)]
42+
[Parameter(ParameterSetName = ServicePrincipalWithPasswordParameterSet,
43+
Mandatory = true, HelpMessage = "Name of the Azure Analysis Services environment to which to logon to")]
44+
[Parameter(ParameterSetName = ServicePrincipalWithCertificateParameterSet,
45+
Mandatory = true, HelpMessage = "Name of the Azure Analysis Services environment to which to logon to")]
3746
public string RolloutEnvironment { get; set; }
38-
39-
[Parameter(Position = 1, Mandatory = false, HelpMessage = "Login credentials to the Azure Analysis Services environment")]
47+
48+
[Parameter(ParameterSetName = UserParameterSet,
49+
Mandatory = false, HelpMessage = "Login credentials to the Azure Analysis Services environment", Position = 1)]
50+
[Parameter(ParameterSetName = ServicePrincipalWithPasswordParameterSet,
51+
Mandatory = true, HelpMessage = "Login credentials to the Azure Analysis Services environment")]
4052
public PSCredential Credential { get; set; }
4153

54+
[Parameter(ParameterSetName = ServicePrincipalWithPasswordParameterSet,
55+
Mandatory = true)]
56+
[Parameter(ParameterSetName = ServicePrincipalWithCertificateParameterSet,
57+
Mandatory = true)]
58+
public SwitchParameter ServicePrincipal { get; set; }
59+
60+
[Parameter(ParameterSetName = ServicePrincipalWithPasswordParameterSet,
61+
Mandatory = true, HelpMessage = "Tenant name or ID")]
62+
[Parameter(ParameterSetName = ServicePrincipalWithCertificateParameterSet,
63+
Mandatory = true, HelpMessage = "Tenant name or ID")]
64+
[ValidateNotNullOrEmpty]
65+
public string TenantId { get; set; }
66+
67+
[Parameter(ParameterSetName = ServicePrincipalWithCertificateParameterSet,
68+
Mandatory = true, HelpMessage = "The application ID.")]
69+
[ValidateNotNullOrEmpty]
70+
public string ApplicationId { get; set; }
71+
72+
[Parameter(ParameterSetName = ServicePrincipalWithCertificateParameterSet,
73+
Mandatory = true, HelpMessage = "Certificate Hash (Thumbprint)")]
74+
[ValidateNotNullOrEmpty]
75+
public string CertificateThumbprint { get; set; }
76+
4277
protected AsAzureEnvironment AsEnvironment;
43-
78+
4479
protected override IAzureContext DefaultContext
4580
{
4681
get
@@ -83,9 +118,30 @@ protected override void InitializeQosEvent()
83118
// nothing to do here.
84119
}
85120

121+
protected override void SetupDebuggingTraces()
122+
{
123+
// nothing to do here.
124+
}
125+
126+
protected override void TearDownDebuggingTraces()
127+
{
128+
// nothing to do here.
129+
}
130+
131+
protected override void SetupHttpClientPipeline()
132+
{
133+
// nothing to do here.
134+
}
135+
136+
protected override void TearDownHttpClientPipeline()
137+
{
138+
// nothing to do here.
139+
}
140+
86141
public override void ExecuteCmdlet()
87142
{
88143
AsAzureAccount azureAccount = new AsAzureAccount();
144+
azureAccount.Type = ServicePrincipal ? AsAzureAccount.AccountType.ServicePrincipal : AsAzureAccount.AccountType.User;
89145

90146
SecureString password = null;
91147
if (Credential != null)
@@ -94,6 +150,20 @@ public override void ExecuteCmdlet()
94150
password = Credential.Password;
95151
}
96152

153+
if (ServicePrincipal)
154+
{
155+
azureAccount.Tenant = TenantId;
156+
157+
if (!string.IsNullOrEmpty(ApplicationId))
158+
{
159+
azureAccount.Id = ApplicationId;
160+
}
161+
if (!string.IsNullOrEmpty(CertificateThumbprint))
162+
{
163+
azureAccount.CertificateThumbprint = CertificateThumbprint;
164+
}
165+
}
166+
97167
if (ShouldProcess(string.Format(Resources.LoginTarget, AsEnvironment.Name), "log in"))
98168
{
99169
var currentProfile = AsAzureClientSession.Instance.Profile;

src/ResourceManager/AnalysisServices/Commands.AnalysisServices.Dataplane/Models/AsAzureAccount.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,18 @@ public partial class AsAzureAccount
2424
public string UniqueId { get; set; }
2525

2626
public string Tenant { get; set; }
27+
28+
public string Type { get; set; }
29+
30+
public string CertificateThumbprint { get; set; }
31+
32+
/// <summary>
33+
/// string constants for known credential types
34+
/// </summary>
35+
public static class AccountType
36+
{
37+
public const string User = "User",
38+
ServicePrincipal = "ServicePrincipal";
39+
}
2740
}
2841
}

src/ResourceManager/AnalysisServices/Commands.AnalysisServices.Dataplane/Models/AsAzureAuthenticationProvider.cs

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
using System.Text;
2121
using System.Threading.Tasks;
2222
using Microsoft.IdentityModel.Clients.ActiveDirectory;
23+
using Microsoft.WindowsAzure.Commands.Common;
24+
using Microsoft.WindowsAzure.Commands.Common.Properties;
2325

2426
namespace Microsoft.Azure.Commands.AnalysisServices.Dataplane.Models
2527
{
@@ -52,7 +54,7 @@ public string GetAadAuthenticatedToken(AsAzureContext asAzureContext, SecureStri
5254
AsAzureClientSession.TokenCache);
5355

5456
AuthenticationResult result = null;
55-
if (password == null)
57+
if (password == null && asAzureContext.Account.Type == AsAzureAccount.AccountType.User)
5658
{
5759
if (asAzureContext.Account.Id != null)
5860
{
@@ -74,13 +76,35 @@ public string GetAadAuthenticatedToken(AsAzureContext asAzureContext, SecureStri
7476
}
7577
else
7678
{
77-
UserCredential userCredential = new UserCredential(asAzureContext.Account.Id, password);
78-
result = authenticationContext.AcquireToken(resourceUri, clientId, userCredential);
79-
}
79+
if (asAzureContext.Account.Type == AsAzureAccount.AccountType.User)
80+
{
81+
UserCredential userCredential = new UserCredential(asAzureContext.Account.Id, password);
82+
result = authenticationContext.AcquireToken(resourceUri, clientId, userCredential);
8083

81-
asAzureContext.Account.Id = result.UserInfo.DisplayableId;
82-
asAzureContext.Account.Tenant = result.TenantId;
83-
asAzureContext.Account.UniqueId = result.UserInfo.UniqueId;
84+
asAzureContext.Account.Id = result.UserInfo.DisplayableId;
85+
asAzureContext.Account.Tenant = result.TenantId;
86+
asAzureContext.Account.UniqueId = result.UserInfo.UniqueId;
87+
}
88+
else if (asAzureContext.Account.Type == AsAzureAccount.AccountType.ServicePrincipal)
89+
{
90+
if (string.IsNullOrEmpty(asAzureContext.Account.CertificateThumbprint))
91+
{
92+
ClientCredential credential = new ClientCredential(asAzureContext.Account.Id, password);
93+
result = authenticationContext.AcquireToken(resourceUri, credential);
94+
}
95+
else
96+
{
97+
DiskDataStore dataStore = new DiskDataStore();
98+
var certificate = dataStore.GetCertificate(asAzureContext.Account.CertificateThumbprint);
99+
if (certificate == null)
100+
{
101+
throw new ArgumentException(string.Format(Resources.CertificateNotFoundInStore, asAzureContext.Account.CertificateThumbprint));
102+
}
103+
104+
result = authenticationContext.AcquireToken(resourceUri, new ClientAssertionCertificate(asAzureContext.Account.Id, certificate));
105+
}
106+
}
107+
}
84108

85109
return result.AccessToken;
86110
}

src/ResourceManager/AnalysisServices/Commands.AnalysisServices.Dataplane/help/Add-AzureAnalysisServicesAccount.md

Lines changed: 121 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
external help file: Microsoft.Azure.Commands.AnalysisServices.Dataplane.dll-help.xml
2+
external help file: Microsoft.Azure.Commands.AnalysisServices.Dataplane.dll-Help.xml
33
online version:
44
schema: 2.0.0
55
---
@@ -11,9 +11,22 @@ Adds an authenticated account to use for Azure Analysis Services server cmdlet r
1111

1212
## SYNTAX
1313

14+
### UserParameterSetName (Default)
1415
```
15-
Add-AzureAnalysisServicesAccount [-RolloutEnvironment] <String> [[-Credential] <PSCredential>] [-WhatIf]
16-
[-Confirm]
16+
Add-AzureAnalysisServicesAccount [[-RolloutEnvironment] <String>] [[-Credential] <PSCredential>] [-WhatIf]
17+
[-Confirm] [<CommonParameters>]
18+
```
19+
20+
### ServicePrincipalWithPasswordParameterSetName
21+
```
22+
Add-AzureAnalysisServicesAccount [-RolloutEnvironment] <String> [-Credential] <PSCredential>
23+
[-ServicePrincipal] -TenantId <String> [-WhatIf] [-Confirm] [<CommonParameters>]
24+
```
25+
26+
### ServicePrincipalWithCertificateParameterSetName
27+
```
28+
Add-AzureAnalysisServicesAccount [-RolloutEnvironment] <String> [-ServicePrincipal] -TenantId <String>
29+
-ApplicationId <String> -CertificateThumbprint <String> [-WhatIf] [-Confirm] [<CommonParameters>]
1730
```
1831

1932
## DESCRIPTION
@@ -30,14 +43,60 @@ Credential: $UserCredential
3043

3144
This example will add the account specified by the $UserCredential variable to the westcentralus.asazure.windows.net Analysis Services environment.
3245

46+
### Example 2
47+
```
48+
PS C:\>$ApplicationCredential = Get-Credential
49+
PS C:\>Add-AzureAnalysisServicesAccount -RolloutEnvironment 'westcentralus.asazure.windows.net' -ServicePrincipal -Credential $ApplicationCredential -TenantId "xxxx-xxxx-xxxx-xxxx"
50+
```
51+
52+
The first command gets the application service principal credentials, and then stores them in the $ApplicationCredential variable.
53+
The second command add the application service principal account specified by the $ApplicationCredential variable and TenantId to the westcentralus.asazure.windows.net Analysis Services environment.
54+
55+
### Example 3
56+
```
57+
PS C:\>Add-AzureAnalysisServicesAccount -RolloutEnvironment 'westcentralus.asazure.windows.net' -ServicePrincipal -ApplicationId "yyyy-yyyy-yyyy-yyyy" -CertificateThumbprint 'zzzzzzzzzzzzzzzz' -TenantId "xxxx-xxxx-xxxx-xxxx"
58+
```
59+
60+
This example will add the application service principal account specified by the ApplicationId, TenantId and CertificateThumbprint to the westcentralus.asazure.windows.net Analysis Services environment.
61+
3362
## PARAMETERS
3463

64+
### -ApplicationId
65+
The application ID.
66+
67+
```yaml
68+
Type: String
69+
Parameter Sets: ServicePrincipalWithCertificateParameterSetName
70+
Aliases:
71+
72+
Required: True
73+
Position: Named
74+
Default value: None
75+
Accept pipeline input: False
76+
Accept wildcard characters: False
77+
```
78+
79+
### -CertificateThumbprint
80+
Certificate Hash (Thumbprint)
81+
82+
```yaml
83+
Type: String
84+
Parameter Sets: ServicePrincipalWithCertificateParameterSetName
85+
Aliases:
86+
87+
Required: True
88+
Position: Named
89+
Default value: None
90+
Accept pipeline input: False
91+
Accept wildcard characters: False
92+
```
93+
3594
### -Credential
3695
Login credentials
3796
3897
```yaml
3998
Type: PSCredential
40-
Parameter Sets: (All)
99+
Parameter Sets: UserParameterSetName
41100
Aliases:
42101

43102
Required: False
@@ -47,12 +106,36 @@ Accept pipeline input: False
47106
Accept wildcard characters: False
48107
```
49108
109+
```yaml
110+
Type: PSCredential
111+
Parameter Sets: ServicePrincipalWithPasswordParameterSetName
112+
Aliases:
113+
114+
Required: True
115+
Position: 1
116+
Default value: None
117+
Accept pipeline input: False
118+
Accept wildcard characters: False
119+
```
120+
50121
### -RolloutEnvironment
51122
Name of the Azure Analysis Services environment to which to logon to. Given the full name of the server for example asazure://westcentralus.asazure.windows.net/testserver , the correct value for this variable will be westcentralus.asazure.windows.net
52123
53124
```yaml
54125
Type: String
55-
Parameter Sets: (All)
126+
Parameter Sets: UserParameterSetName
127+
Aliases:
128+
129+
Required: False
130+
Position: 0
131+
Default value: None
132+
Accept pipeline input: False
133+
Accept wildcard characters: False
134+
```
135+
136+
```yaml
137+
Type: String
138+
Parameter Sets: ServicePrincipalWithPasswordParameterSetName, ServicePrincipalWithCertificateParameterSetName
56139
Aliases:
57140

58141
Required: True
@@ -62,6 +145,36 @@ Accept pipeline input: False
62145
Accept wildcard characters: False
63146
```
64147
148+
### -ServicePrincipal
149+
Indicates that this account authenticates by providing service principal credentials.
150+
151+
```yaml
152+
Type: SwitchParameter
153+
Parameter Sets: ServicePrincipalWithPasswordParameterSetName, ServicePrincipalWithCertificateParameterSetName
154+
Aliases:
155+
156+
Required: True
157+
Position: Named
158+
Default value: None
159+
Accept pipeline input: False
160+
Accept wildcard characters: False
161+
```
162+
163+
### -TenantId
164+
Tenant name or ID
165+
166+
```yaml
167+
Type: String
168+
Parameter Sets: ServicePrincipalWithPasswordParameterSetName, ServicePrincipalWithCertificateParameterSetName
169+
Aliases:
170+
171+
Required: True
172+
Position: Named
173+
Default value: None
174+
Accept pipeline input: False
175+
Accept wildcard characters: False
176+
```
177+
65178
### -Confirm
66179
Prompts you for confirmation before running the cmdlet.
67180
@@ -93,6 +206,9 @@ Accept pipeline input: False
93206
Accept wildcard characters: False
94207
```
95208
209+
### CommonParameters
210+
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
211+
96212
## INPUTS
97213
98214
## OUTPUTS

src/ResourceManager/AnalysisServices/Commands.AnalysisServices.Test/ScenarioTests/AsTests.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,12 @@ public void TestAnalysisServicesServerRestart()
6565
{
6666
NewInstance.RunPsTest("Test-AnalysisServicesServerRestart");
6767
}
68+
69+
[Fact]
70+
[Trait(Category.ServiceManagement, Category.LiveOnly)]
71+
public void TestAnalysisServicesServerLoginWithSPN()
72+
{
73+
NewInstance.RunPsTest("Test-AnalysisServicesServerLoginWithSPN");
74+
}
6875
}
6976
}

0 commit comments

Comments
 (0)