public async Task <AzureServicePrincipal> GetServicePrincipalAsync(string servicePrincipalName) { if (string.IsNullOrWhiteSpace(servicePrincipalName)) { throw new ArgumentException("Must not NULL or WHITESPACE", nameof(servicePrincipalName)); } var servicePrincipal = await GetServicePrincipalInternalAsync(servicePrincipalName) .ConfigureAwait(false); if (servicePrincipal is null) { return(null); } var serviceApplication = await GetServiceApplicationInternalAsync(servicePrincipalName) .ConfigureAwait(false); if (serviceApplication is null) { return(null); } var azureServicePrincipal = new AzureServicePrincipal() { ObjectId = Guid.Parse(servicePrincipal.Id), ApplicationId = Guid.Parse(servicePrincipal.ApplicationId), Name = servicePrincipal.Name }; var token = await azureSessionService .AcquireTokenAsync(AzureEndpoint.GraphEndpoint) .ConfigureAwait(false); var json = await $"https://graph.windows.net/{azureSessionService.Options.TenantId}/applications/{serviceApplication.Inner.ObjectId}" .SetQueryParam("api-version", "1.6") .WithOAuthBearerToken(token) .GetJObjectAsync() .ConfigureAwait(false); var identifier = Convert.ToBase64String(azureServicePrincipal.ObjectId.ToByteArray()); var expiresOn = json.SelectToken($"$.value[?(@.customKeyIdentifier == '{identifier}')].endDate")?.ToString(); if (!string.IsNullOrEmpty(expiresOn) && DateTime.TryParse(expiresOn, out var expiresOnDateTime)) { azureServicePrincipal.ExpiresOn = expiresOnDateTime; } return(azureServicePrincipal); }
public async Task <AzureServicePrincipal> CreateServicePrincipalAsync(string name, string password = null) { if (name is null) { throw new ArgumentNullException(nameof(name)); } name = SanitizeServicePrincipalName(name); using var client = azureSessionService .CreateClient <GraphRbacManagementClient>(AzureEndpoint.GraphEndpoint); password ??= CreateServicePrincipalPassword(); var expiresOn = DateTime.UtcNow.AddYears(1); var parameters = new ApplicationCreateParameters() { DisplayName = name, AvailableToOtherTenants = false, IdentifierUris = new List <string> { $"http://{name}" }, RequiredResourceAccess = new List <RequiredResourceAccess> { new RequiredResourceAccess { ResourceAppId = "00000003-0000-0000-c000-000000000000", ResourceAccess = new List <ResourceAccess> { new ResourceAccess { Id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d", Type = "Scope" } } } } }; var application = await client.Applications .CreateAsync(parameters) .ConfigureAwait(false); var principal = await client.ServicePrincipals .CreateAsync(new ServicePrincipalCreateParameters { AppId = application.AppId }) .ConfigureAwait(false); await client.Applications .UpdatePasswordCredentialsAsync(application.ObjectId, new List <PasswordCredential> { new PasswordCredential { StartDate = DateTime.UtcNow, EndDate = expiresOn, KeyId = Guid.NewGuid().ToString(), Value = password, CustomKeyIdentifier = Guid.Parse(principal.ObjectId).ToByteArray() } }).ConfigureAwait(false); var azureServicePrincipal = new AzureServicePrincipal() { ObjectId = Guid.Parse(principal.ObjectId), ApplicationId = Guid.Parse(principal.AppId), Name = principal.ServicePrincipalNames.FirstOrDefault(), Password = password, ExpiresOn = expiresOn }; return(azureServicePrincipal); }