Skip to content

Clu #235

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

Merged
merged 10 commits into from
Dec 9, 2015
Merged

Clu #235

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 @@ -35,17 +35,17 @@ public AdalTokenProvider()

public IAccessToken GetAccessToken(
AdalConfiguration config,
ShowDialog promptBehavior,
AuthenticationBehavior behavior,
string userId,
string password,
AzureAccount.AccountType credentialType)
{
switch (credentialType)
{
case AzureAccount.AccountType.User:
return userTokenProvider.GetAccessToken(config, promptBehavior, userId, password, credentialType);
return userTokenProvider.GetAccessToken(config, behavior, userId, password, credentialType);
case AzureAccount.AccountType.ServicePrincipal:
return servicePrincipalTokenProvider.GetAccessToken(config, promptBehavior, userId, password, credentialType);
return servicePrincipalTokenProvider.GetAccessToken(config, behavior, userId, password, credentialType);
default:
throw new ArgumentException(Resources.UnknownCredentialType, "credentialType");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,21 @@
// limitations under the License.
// ----------------------------------------------------------------------------------

using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;

namespace Microsoft.Azure.Commands.Common.Authentication
{
public enum ShowDialog
public enum AuthenticationType
{
Auto,
Always,
Never
DeviceCode,
Silent
}

public class AuthenticationBehavior
{
public Func<DeviceCodeResult, bool> DeviceCodeHandler { get; set; }

public AuthenticationType Type { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ public interface ITokenProvider
/// and credential type.
/// </summary>
/// <param name="config">Configuration.</param>
/// <param name="promptBehavior">Prompt behavior.</param>
/// <param name="behavior">Prompt behavior.</param>
/// <param name="userId">User ID/Service principal to get the token for.</param>
/// <param name="password">Secure strings with password/service principal key.</param>
/// <param name="credentialType">Credential type.</param>
/// <returns>An access token.</returns>
IAccessToken GetAccessToken(
AdalConfiguration config,
ShowDialog promptBehavior,
AuthenticationBehavior behavior,
string userId,
string password,
AzureAccount.AccountType credentialType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ public KeyStoreApplicationCredentialProvider(string tenant, string password)
/// <returns></returns>
public async Task<AuthenticationResult> AuthenticateAsync(string clientId, string audience, AuthenticationContext context)
{


return await context.AcquireTokenAsync(audience, new ClientCredential(clientId, _password));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public ServicePrincipalTokenProvider(Func<String, byte[]> certificateFinder)
{
_getCertificate = certificateFinder;
}
public IAccessToken GetAccessToken(AdalConfiguration config, ShowDialog promptBehavior, string userId, string password,
public IAccessToken GetAccessToken(AdalConfiguration config, AuthenticationBehavior behavior, string userId, string password,
AzureAccount.AccountType credentialType)
{
if (credentialType == AzureAccount.AccountType.User)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using System.Runtime.InteropServices;
using Commands.Common.Authentication.Properties;
using Microsoft.Rest.Azure.Authentication;
using System.Management.Automation;

namespace Microsoft.Azure.Commands.Common.Authentication
{
Expand All @@ -29,10 +30,9 @@ namespace Microsoft.Azure.Commands.Common.Authentication
/// </summary>
internal class UserTokenProvider : ITokenProvider
{

public IAccessToken GetAccessToken(
AdalConfiguration config,
ShowDialog promptBehavior,
AuthenticationBehavior behavior,
string userId,
string password,
AzureAccount.AccountType credentialType)
Expand All @@ -42,7 +42,7 @@ public IAccessToken GetAccessToken(
throw new ArgumentException(string.Format(Resources.InvalidCredentialType, "User"), "credentialType");
}

return new AdalAccessToken(AcquireToken(config, promptBehavior, userId, password), this, config);
return new AdalAccessToken(AcquireToken(config, behavior, userId, password), this, config);
}

private readonly static TimeSpan expirationThreshold = TimeSpan.FromMinutes(5);
Expand Down Expand Up @@ -81,7 +81,7 @@ private void Renew(AdalAccessToken token)
if (IsExpired(token))
{
ServiceClientTracing.Information(Resources.UPNExpiredTokenTrace);
AuthenticationResult result = AcquireToken(token.Configuration, ShowDialog.Never, token.UserId, null);
AuthenticationResult result = AcquireToken(token.Configuration, new AuthenticationBehavior { Type = AuthenticationType.Silent }, token.UserId, null);

if (result == null)
{
Expand All @@ -104,7 +104,7 @@ private AuthenticationContext CreateContext(AdalConfiguration config)

// 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, ShowDialog promptBehavior, string userId,
private AuthenticationResult AcquireToken(AdalConfiguration config, AuthenticationBehavior behavior, string userId,
string password)
{
AuthenticationResult result = null;
Expand All @@ -121,31 +121,64 @@ private AuthenticationResult AcquireToken(AdalConfiguration config, ShowDialog p
config.AdEndpoint,
config.ClientId,
config.ClientRedirectUri);
if (promptBehavior != ShowDialog.Never)
if (behavior.Type == AuthenticationType.DeviceCode)
{
throw new NotImplementedException("Device based authencation is not implemented.");
}
if(behavior.DeviceCodeHandler == null)
{
throw new PSArgumentException("deviceCodeHandler");
}

try
{
UserCredential credential = new UserCredential(userId, password);
result = context.AcquireTokenAsync(
config.ResourceClientUri,
config.ClientId,
credential)
.ConfigureAwait(false).GetAwaiter().GetResult();
return result;
try
{
DeviceCodeResult codeResult = context.AcquireDeviceCodeAsync(
config.ResourceClientUri,
config.ClientId)
.ConfigureAwait(false).GetAwaiter().GetResult();

if (behavior.DeviceCodeHandler(codeResult))
{
return context.AcquireTokenByDeviceCodeAsync(codeResult)
.ConfigureAwait(false).GetAwaiter().GetResult();
}

throw new AadAuthenticationCanceledException("Authentication cancelled.", null);
}
catch (AdalException adalException)
{
if (adalException.ErrorCode == AdalError.AuthenticationCanceled)
{
throw new AadAuthenticationCanceledException(adalException.Message, adalException);
}

throw new AadAuthenticationFailedException(adalException.Message, adalException);
}
}
catch (AdalException adalException)
else if(behavior.Type == AuthenticationType.Silent)
{
if (adalException.ErrorCode == AdalError.AuthenticationCanceled)
try
{
throw new AadAuthenticationCanceledException(adalException.Message, adalException);
UserCredential credential = new UserCredential(userId, password);
return context.AcquireTokenAsync(
config.ResourceClientUri,
config.ClientId,
credential)
.ConfigureAwait(false).GetAwaiter().GetResult();
}
catch (AdalException adalException)
{
if (adalException.ErrorCode == AdalError.AuthenticationCanceled)
{
throw new AadAuthenticationCanceledException(adalException.Message, adalException);
}

throw new AadAuthenticationFailedException(adalException.Message, adalException);
throw new AadAuthenticationFailedException(adalException.Message, adalException);
}
}
else
{
throw new NotImplementedException(
string.Format("'{0}' authentication is not implemented.", behavior.Type));
}

}

/// <summary>
Expand Down Expand Up @@ -187,8 +220,7 @@ public LoginType LoginType
}
}
}



private void ClearCookies()
{
NativeMethods.InternetSetOption(IntPtr.Zero, NativeMethods.INTERNET_OPTION_END_BROWSER_SESSION, IntPtr.Zero, 0);
Expand Down
23 changes: 17 additions & 6 deletions src/CLU/Commands.Common.Authentication/AuthenticationFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ public IAccessToken Authenticate(
AzureAccount account,
AzureEnvironment environment,
string tenant,
string password,
string password,
AuthenticationBehavior behavior,
TokenCache tokenCache,
AzureEnvironment.Endpoint resourceId = AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId)
{
Expand All @@ -64,8 +65,7 @@ public IAccessToken Authenticate(
}
else
{

token = TokenProvider.GetAccessToken(configuration, ShowDialog.Never, account.Id, password, account.Type);
token = TokenProvider.GetAccessToken(configuration, behavior, account.Id, password, account.Type);
}

account.Id = token.UserId;
Expand All @@ -79,7 +79,14 @@ public IAccessToken Authenticate(
string password,
AzureEnvironment.Endpoint resourceId = AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId)
{
return Authenticate(account, environment, tenant, password, TokenCache.DefaultShared, resourceId);
return Authenticate(
account,
environment,
tenant,
password,
new AuthenticationBehavior { Type = AuthenticationType.Silent },
TokenCache.DefaultShared,
resourceId);
}

public ServiceClientCredentials GetSubscriptionCloudCredentials(AzureContext context)
Expand Down Expand Up @@ -151,8 +158,12 @@ public ServiceClientCredentials GetSubscriptionCloudCredentials(
tokenCache = new TokenCache(context.TokenCache);
}

var token = Authenticate(context.Account, context.Environment,
tenant, null, tokenCache);
var token = Authenticate(
context.Account,
context.Environment,
tenant, null,
new AuthenticationBehavior { Type = AuthenticationType.Silent },
tokenCache);

if (context.TokenCache != null && context.TokenCache.Length > 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,16 @@ public interface IAuthenticationFactory
/// <param name="environment">The azure environment object</param>
/// <param name="tenant">The AD tenant in most cases should be 'common'</param>
/// <param name="password">The AD account password</param>
/// <param name="behavior">The authentication behavior</param>
/// <param name="tokenCache">Token Cache</param>
/// <param name="resourceId">Optional, the AD resource id</param>
/// <returns></returns>
IAccessToken Authenticate(
AzureAccount account,
AzureEnvironment environment,
string tenant,
string password,
string password,
AuthenticationBehavior behavior,
TokenCache tokenCache,
AzureEnvironment.Endpoint resourceId = AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId);

Expand All @@ -56,6 +58,7 @@ IAccessToken Authenticate(
AzureEnvironment.Endpoint resourceId = AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId);

ServiceClientCredentials GetSubscriptionCloudCredentials(AzureContext context);

ServiceClientCredentials GetSubscriptionCloudCredentials(AzureContext context, AzureEnvironment.Endpoint targetEndpoint);

ServiceClientCredentials GetServiceClientCredentials(AzureContext context);
Expand Down
2 changes: 1 addition & 1 deletion src/CLU/Commands.Common.Authentication/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"System.Linq": "4.0.1-beta-23516",
"Microsoft.CLU": "1.0.0",
"Microsoft.IdentityModel.Clients.ActiveDirectory": "3.6.210231457-alpha",
"Microsoft.Rest.ClientRuntime": "1.4.1",
"Microsoft.Rest.ClientRuntime": "1.5.0",
"Microsoft.Rest.ClientRuntime.Azure.Authentication": "1.0.0-preview",
"Newtonsoft.Json": "7.0.1",
"System.Collections": "4.0.11-beta-23516",
Expand Down
2 changes: 1 addition & 1 deletion src/CLU/Commands.Common.Storage/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"Commands.Common": "",
"Commands.Common.Authentication": "",
"Microsoft.IdentityModel.Clients.ActiveDirectory": "3.6.210231457-alpha",
"Microsoft.Rest.ClientRuntime": "1.4.1",
"Microsoft.Rest.ClientRuntime": "1.5.0",
"Newtonsoft.Json": "7.0.1",
"System.Collections": "4.0.11-beta-23516",
"System.Collections.Concurrent": "4.0.11-beta-23516",
Expand Down
26 changes: 18 additions & 8 deletions src/CLU/Commands.Common/AzurePSCmdlet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,16 @@ protected virtual T GetSessionVariableValue<T>(string name, T defaultValue) wher
{
try
{
returnValue = SessionState.PSVariable.Get<T>(name)?? defaultValue ;
returnValue = SessionState.PSVariable.Get<T>(name) ?? defaultValue;
}
catch
{
}
}
else
{
try
{
var variablePath = GetPath(name);
var fileText = DataStore.ReadFileAsText(variablePath);
if (!string.IsNullOrEmpty(fileText))
Expand All @@ -117,6 +126,7 @@ protected virtual T GetSessionVariableValue<T>(string name, T defaultValue) wher
}
catch
{

}
}

Expand All @@ -127,11 +137,15 @@ protected virtual string GetPath(string variableName)
{
return Path.Combine(Directory.GetCurrentDirectory(), "sessions", variableName);
}

protected virtual void SetSessionVariable<T>(string name, T value) where T : class
{
if (SessionState != null)
{
SessionState.PSVariable.Set(name, value);
}
else
{
var variablePath = GetPath(name);
DataStore.WriteFile(variablePath, JsonConvert.SerializeObject(value));
}
Expand All @@ -152,12 +166,12 @@ protected static void InitializeDataCollectionProfile()
{
if (string.Equals(value, bool.FalseString, StringComparison.OrdinalIgnoreCase))
{
// Disable data collection only if it is explictly set to 'false'.
// Disable data collection only if it is explicitly set to 'false'.
_dataCollectionProfile = new AzurePSDataCollectionProfile(true);
}
else if (string.Equals(value, bool.TrueString, StringComparison.OrdinalIgnoreCase))
{
// Enable data collection only if it is explictly set to 'true'.
// Enable data collection only if it is explicitly set to 'true'.
_dataCollectionProfile = new AzurePSDataCollectionProfile(false);
}
}
Expand Down Expand Up @@ -270,7 +284,7 @@ protected override void BeginProcessing()
WriteDebugWithTimestamp(string.Format("using account id '{0}'...", DefaultContext.Account.Id));
}

DataStore = GetSessionVariableValue<IDataStore>(AzurePowerShell.DataStoreVariable, new DiskDataStore());
DataStore = DataStore?? GetSessionVariableValue<IDataStore>(AzurePowerShell.DataStoreVariable, new DiskDataStore());
_adalListener = _adalListener ?? new DebugStreamTraceListener(_debugMessages);
DebugStreamTraceListener.AddAdalTracing(_adalListener);

Expand Down Expand Up @@ -339,11 +353,7 @@ protected bool IsVerbose()
protected new void WriteObject(object sendToPipeline)
{
FlushDebugMessages();
#if DEBUG
CommandRuntime.WriteObject(sendToPipeline);
#else
base.WriteObject(sendToPipeline);
#endif
}

protected new void WriteObject(object sendToPipeline, bool enumerateCollection)
Expand Down
Loading