/// <summary> /// Acquires the security token from the authority. /// </summary> /// <param name="account">The account information to be used when generating the client.</param> /// <param name="environment">The environment where the client is connecting.</param> /// <param name="scopes">Scopes requested to access a protected service.</param> /// <param name="message">The message to be written to the console.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param> /// <returns>The result from the authentication request.</returns> public async Task <AuthenticationResult> AuthenticateAsync(MgmtAccount account, MgmtEnvironment environment, IEnumerable <string> scopes, string message = null, CancellationToken cancellationToken = default) { AuthenticationResult authResult = null; IAuthenticator processAuthenticator = Builder.Authenticator; while (processAuthenticator != null && authResult == null) { authResult = await processAuthenticator.TryAuthenticateAsync(GetAuthenticationParameters(account, environment, scopes, message), cancellationToken).ConfigureAwait(false); if (authResult != null) { if (authResult.Account?.HomeAccountId != null) { account.Identifier = authResult.Account.HomeAccountId.Identifier; account.ObjectId = authResult.Account.HomeAccountId.ObjectId; } if (account.Tenant.Equals("organizations", StringComparison.InvariantCultureIgnoreCase) && !string.IsNullOrEmpty(authResult.TenantId)) { account.Tenant = authResult.TenantId; } break; } processAuthenticator = processAuthenticator.NextAuthenticator; } return(authResult); }
/// <summary> /// Gets the parameters used to perform authentication.. /// </summary> /// <param name="account">The account information to be used when generating the client.</param> /// <param name="environment">The environment where the client is connecting.</param> /// <param name="scopes">Scopes requested to access a protected service.</param> /// <param name="message">The message to be written to the console.</param> /// <returns>The parameters used to perform authentication.</returns> private AuthenticationParameters GetAuthenticationParameters(MgmtAccount account, MgmtEnvironment environment, IEnumerable <string> scopes, string message = null) { if (account.IsPropertySet(MgmtAccountPropertyType.AccessToken)) { return(new AccessTokenParameters(account, environment, scopes)); } else if (account.IsPropertySet("UseAuthCode")) { return(new InteractiveParameters(account, environment, scopes, message)); } else if (account.IsPropertySet(MgmtAccountPropertyType.RefreshToken)) { return(new RefreshTokenParameters(account, environment, scopes)); } else if (account.Type == AccountType.User) { if (!string.IsNullOrEmpty(account.ObjectId)) { return(new SilentParameters(account, environment, scopes)); } else if (account.IsPropertySet("UseDeviceAuth")) { return(new DeviceCodeParameters(account, environment, scopes)); } return(new InteractiveParameters(account, environment, scopes, message)); } else if (account.Type == AccountType.Certificate || account.Type == AccountType.ServicePrincipal) { return(new ServicePrincipalParameters(account, environment, scopes)); } return(null); }
/// <summary> /// Gets an aptly configured client. /// </summary> /// <param name="account">The account information to be used when generating the client.</param> /// <param name="environment">The environment where the client is connecting.</param> /// <param name="redirectUri">The redirect URI for the client.</param> /// <returns>An aptly configured client.</returns> public IClientApplicationBase GetClient(MgmtAccount account, MgmtEnvironment environment, string redirectUri = null) { IClientApplicationBase app; if (account.IsPropertySet(MgmtAccountPropertyType.CertificateThumbprint) || account.IsPropertySet(MgmtAccountPropertyType.ServicePrincipalSecret)) { app = CreateConfidentialClient( GetAzureCloudInstance(environment), account.GetProperty(MgmtAccountPropertyType.ApplicationId), account.GetProperty(MgmtAccountPropertyType.ServicePrincipalSecret), GetCertificate(account.GetProperty(MgmtAccountPropertyType.CertificateThumbprint)), redirectUri, account.Tenant); } else { app = CreatePublicClient( GetAzureCloudInstance(environment), account.GetProperty(MgmtAccountPropertyType.ApplicationId), redirectUri, account.Tenant); } return(app); }
/// <summary> /// Initializes a new instance of the <see cref="AuthenticationParameters" /> class. /// </summary> protected AuthenticationParameters(MgmtAccount account, MgmtEnvironment environment, IEnumerable <string> scopes) { account.AssertNotNull(nameof(account)); environment.AssertNotNull(nameof(environment)); scopes.AssertNotNull(nameof(scopes)); Account = account; Environment = environment; Scopes = scopes; }
/// <summary> /// Authenticates the specified request message. /// </summary> /// <param name="request">The HTTP request to be authenticated.</param> /// <returns>An instance of the <see cref="Task"/> class that represents the asynchronous operation.</returns> public async Task AuthenticateRequestAsync(HttpRequestMessage request) { request.AssertNotNull(nameof(request)); MgmtAccount account = MgmtSession.Instance.Context.Account.Clone(); if (!string.IsNullOrEmpty(tenantId)) { account.Tenant = tenantId; } AuthenticationResult authResult = await MgmtSession.Instance.AuthenticationFactory.AuthenticateAsync( account, MgmtSession.Instance.Context.Environment, new[] { $"{MgmtSession.Instance.Context.Environment.GraphEndpoint}/.default" }).ConfigureAwait(false); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken); await Task.CompletedTask.ConfigureAwait(false); }
/// <summary> /// Initializes a new instance of the <see cref="RefreshTokenParameters" /> class. /// </summary> public RefreshTokenParameters(MgmtAccount account, MgmtEnvironment environment, IEnumerable <string> scopes) : base(account, environment, scopes) { }
/// <summary> /// Initializes a new instance of the <see cref="InteractiveParameters" /> class. /// </summary> public InteractiveParameters(MgmtAccount account, MgmtEnvironment environment, IEnumerable <string> scopes, string message) : base(account, environment, scopes) { Message = message; }
/// <summary> /// Executes the operations associated with the cmdlet. /// </summary> public override void ExecuteCmdlet() { Scheduler.RunTask(async() => { MgmtAccount account = new MgmtAccount(); string applicationId; if (!string.IsNullOrEmpty(CertificateThumbprint)) { account.SetProperty(MgmtAccountPropertyType.CertificateThumbprint, CertificateThumbprint); } if (ParameterSetName.Equals(RefreshTokenParameterSet, StringComparison.InvariantCultureIgnoreCase)) { if (Credential != null) { account.ObjectId = Credential.UserName; account.SetProperty(MgmtAccountPropertyType.ServicePrincipalSecret, Credential.Password.ConvertToString()); applicationId = Credential.UserName; } else { applicationId = ApplicationId; } } else if (ParameterSetName.Equals(ServicePrincipalCertificateParameterSet, StringComparison.InvariantCultureIgnoreCase)) { account.SetProperty(MgmtAccountPropertyType.ApplicationId, ApplicationId); account.Type = AccountType.Certificate; applicationId = ApplicationId; } else if (ParameterSetName.Equals(ServicePrincipalParameterSet, StringComparison.InvariantCultureIgnoreCase)) { account.ObjectId = Credential.UserName; account.SetProperty(MgmtAccountPropertyType.ServicePrincipalSecret, Credential.Password.ConvertToString()); account.Type = AccountType.ServicePrincipal; applicationId = ApplicationId; } else { account.Type = AccountType.User; applicationId = ApplicationId; } if (UseAuthorizationCode.IsPresent) { account.SetProperty(MgmtAccountPropertyType.UseAuthCode, "true"); } if (UseDeviceAuthentication.IsPresent) { account.SetProperty(MgmtAccountPropertyType.UseDeviceAuth, "true"); } if (!string.IsNullOrEmpty(RefreshToken)) { account.SetProperty(MgmtAccountPropertyType.RefreshToken, RefreshToken); } account.SetProperty(MgmtAccountPropertyType.ApplicationId, applicationId); account.Tenant = string.IsNullOrEmpty(Tenant) ? "organizations" : Tenant; AuthenticationResult authResult = await MgmtSession.Instance.AuthenticationFactory.AuthenticateAsync( account, MgmtEnvironment.PublicEnvironments[Environment], Scopes, Message, CancellationToken).ConfigureAwait(false); AuthResult result = new AuthResult( authResult.AccessToken, authResult.IsExtendedLifeTimeToken, authResult.UniqueId, authResult.ExpiresOn, authResult.ExtendedExpiresOn, authResult.TenantId, authResult.Account, authResult.IdToken, authResult.Scopes, authResult.CorrelationId); byte[] cacheData = null; if (MgmtSession.Instance.TryGetComponent(ComponentKey.TokenCache, out IMgmtTokenCache tokenCache)) { cacheData = tokenCache.GetCacheData(); if (cacheData?.Length > 0) { IEnumerable <string> knownPropertyNames = new[] { "AccessToken", "RefreshToken", "IdToken", "Account", "AppMetadata" }; JObject root = JObject.Parse(Encoding.UTF8.GetString(cacheData, 0, cacheData.Length)); IDictionary <string, JToken> known = (root as IDictionary <string, JToken>) .Where(kvp => knownPropertyNames.Any(p => string.Equals(kvp.Key, p, StringComparison.OrdinalIgnoreCase))) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); IDictionary <string, TokenCacheItem> tokens = new Dictionary <string, TokenCacheItem>(); if (known.ContainsKey("RefreshToken")) { foreach (JToken token in root["RefreshToken"].Values()) { if (token is JObject j) { TokenCacheItem item = new TokenCacheItem { ClientId = ExtractExistingOrEmptyString(j, "client_id"), CredentialType = ExtractExistingOrEmptyString(j, "credential_type"), Environment = ExtractExistingOrEmptyString(j, "environment"), HomeAccountId = ExtractExistingOrEmptyString(j, "home_account_id"), RawClientInfo = ExtractExistingOrEmptyString(j, "client_info"), Secret = ExtractExistingOrEmptyString(j, "secret") }; tokens.Add($"{item.HomeAccountId}-{item.Environment}-RefreshToken-{item.ClientId}--", item); } } } if (authResult.Account != null) { string key = tokenCache.GetCacheKey(authResult); if (tokens.ContainsKey(key)) { result.RefreshToken = tokens[key].Secret; } } } else { WriteDebug("There was not any data in the token cache, so a refresh token could not be retrieved."); } } else { WriteDebug("Unable to find a registered token cache."); } WriteObject(result); }); }
/// <summary> /// Initializes a new instance of the <see cref="DeviceCodeParameters" /> class. /// </summary> public DeviceCodeParameters(MgmtAccount account, MgmtEnvironment environment, IEnumerable <string> scopes) : base(account, environment, scopes) { }
/// <summary> /// Executes the operations associated with the cmdlet. /// </summary> public override void ExecuteCmdlet() { Scheduler.RunTask(async() => { MgmtAccount account = new MgmtAccount(); MgmtEnvironment environment = MgmtEnvironment.PublicEnvironments[Environment]; if (!string.IsNullOrEmpty(CertificateThumbprint)) { account.SetProperty(MgmtAccountPropertyType.CertificateThumbprint, CertificateThumbprint); } if (!string.IsNullOrEmpty(RefreshToken)) { account.SetProperty(MgmtAccountPropertyType.RefreshToken, RefreshToken); } account.SetProperty(MgmtAccountPropertyType.ApplicationId, string.IsNullOrEmpty(ApplicationId) ? PowerShellApplicationId : ApplicationId); if (ParameterSetName.Equals(AccessTokenParameterSet, StringComparison.InvariantCultureIgnoreCase)) { account.SetProperty(MgmtAccountPropertyType.AccessToken, AccessToken); account.Type = AccountType.AccessToken; } else if (ParameterSetName.Equals(RefreshTokenParameterSet, StringComparison.InvariantCultureIgnoreCase)) { if (Credential != null) { account.ObjectId = Credential.UserName; account.SetProperty(MgmtAccountPropertyType.ApplicationId, Credential.UserName); account.SetProperty(MgmtAccountPropertyType.ServicePrincipalSecret, Credential.Password.ConvertToString()); } } else if (ParameterSetName.Equals(ServicePrincipalCertificateParameterSet, StringComparison.InvariantCultureIgnoreCase)) { account.SetProperty(MgmtAccountPropertyType.ApplicationId, ApplicationId); account.Type = AccountType.Certificate; } else if (ParameterSetName.Equals(ServicePrincipalParameterSet, StringComparison.InvariantCultureIgnoreCase)) { account.ObjectId = Credential.UserName; account.Type = AccountType.ServicePrincipal; account.SetProperty(MgmtAccountPropertyType.ApplicationId, Credential.UserName); account.SetProperty(MgmtAccountPropertyType.ServicePrincipalSecret, Credential.Password.ConvertToString()); } else { account.Type = AccountType.User; } if (UseDeviceAuthentication.IsPresent) { account.SetProperty("UseDeviceAuth", "true"); } account.SetProperty(MgmtAccountPropertyType.Scope, $"{environment.GraphEndpoint}/.default"); account.Tenant = string.IsNullOrEmpty(Tenant) ? "organizations" : Tenant; await MgmtSession.Instance.AuthenticationFactory.AuthenticateAsync( account, environment, new[] { account.GetProperty(MgmtAccountPropertyType.Scope) }, Message, CancellationToken).ConfigureAwait(false); MgmtSession.Instance.Context = new MgmtContext { Account = account, Environment = environment }; WriteObject(MgmtSession.Instance.Context); }); }
/// <summary> /// Initializes a new instance of the <see cref="ServicePrincipalParameters" /> class. /// </summary> public ServicePrincipalParameters(MgmtAccount account, MgmtEnvironment environment, IEnumerable <string> scopes) : base(account, environment, scopes) { }