// GET: AppServiceCertificate public async Task <ActionResult> Index(string authError) { AppServiceCertificates appServiceCertificates = new AppServiceCertificates(); OAuthTokenSet usertoken = new OAuthTokenSet(); Models.AzureRMWebCertificates.AzureRMWebCertificatesList azureRMWebCertificatesList = new Models.AzureRMWebCertificates.AzureRMWebCertificatesList(); Models.AzureRMWebSites.ResourceManagerWebSites resourceManagerWebSites = new Models.AzureRMWebSites.ResourceManagerWebSites(); // Always setup the OAuth /authorize URI to use Uri redirectUri = new Uri(Request.Url.GetLeftPart(UriPartial.Authority).ToString() + "/OAuth"); string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier").Value; string state = GenerateState(userObjectID, Request.Url.ToString()); string msoauthUri = string.Format("{0}/oauth2/authorize?resource={1}&client_id={2}&response_type=code&redirect_uri={3}&state={4}", Startup.Authority, Url.Encode(Startup.resourceGroupsId), Startup.clientId, Url.Encode(redirectUri.ToString()), state); ViewBag.AuthorizationUrl = msoauthUri; // If we are loaded and we have no credentials, we will create a UserToken object to store the state that we include // in the link we construct to the Authorization endpoint. Once the user completes authorization, the OAuthController // will look up the user token that we created and fill it in with the tokens it obtains. if (authError != null) { usertoken.state = state; usertoken.userId = userObjectID; usertoken.resourceName = Startup.resourceGroupsId; model.OAuthTokens.Add(usertoken); await model.SaveChangesAsync(); return(View(appServiceCertificates)); } else { // Check local OAuthDataStore to see if we have previously cached OAuth bearer tokens for this user. IEnumerable <OAuthTokenSet> query = from OAuthTokenSet in model.OAuthTokens where OAuthTokenSet.userId == userObjectID && OAuthTokenSet.resourceName == Startup.resourceGroupsId select OAuthTokenSet; if (query.GetEnumerator().MoveNext() == false) { usertoken.state = state; usertoken.userId = userObjectID; usertoken.resourceName = Startup.resourceGroupsId; model.OAuthTokens.Add(usertoken); await model.SaveChangesAsync(); authError = "AuthorizationRequired"; } else { usertoken = query.First(); appServiceCertificates.AccessToken = usertoken.accessToken; appServiceCertificates.RefreshToken = usertoken.refreshToken; appServiceCertificates.AccessTokenExpiry = usertoken.accessTokenExpiry; authError = null; string requestUrl = String.Format( CultureInfo.InvariantCulture, Startup.resourceGroupsUrl, HttpUtility.UrlEncode(Startup.subscriptionId)); HttpClient client = new HttpClient(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUrl); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", usertoken.accessToken); HttpResponseMessage response = await client.SendAsync(request); string responseString = await response.Content.ReadAsStringAsync(); ResourceGroups resourceGroups = JsonConvert.DeserializeObject <ResourceGroups>(responseString); foreach (Value v in resourceGroups.value) { requestUrl = String.Format( CultureInfo.InvariantCulture, Startup.resourceManagerWebSitesUrl, HttpUtility.UrlEncode(Startup.subscriptionId), HttpUtility.UrlEncode(v.name)); client = new HttpClient(); request = new HttpRequestMessage(HttpMethod.Get, requestUrl); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", usertoken.accessToken); response = await client.SendAsync(request); responseString = await response.Content.ReadAsStringAsync(); Models.AzureRMWebSites.ResourceManagerWebSiteInfo resourceManagerWebSiteInfo = JsonConvert.DeserializeObject <Models.AzureRMWebSites.ResourceManagerWebSiteInfo>(responseString); resourceManagerWebSites.webSites.Add(resourceManagerWebSiteInfo); AppServiceCertificate appServiceCertificate = new AppServiceCertificate(); foreach (Models.AzureRMWebSites.Value wsv in resourceManagerWebSiteInfo.value) { foreach (Models.AzureRMWebSites.Hostnamesslstate sslstate in wsv.properties.hostNameSslStates) { if (sslstate.sslState == 1) { appServiceCertificate.SiteName = sslstate.name; } } } requestUrl = String.Format( CultureInfo.InvariantCulture, Startup.resourceManagerWebCertificatesUrl, HttpUtility.UrlEncode(Startup.subscriptionId), HttpUtility.UrlEncode(v.name)); client = new HttpClient(); request = new HttpRequestMessage(HttpMethod.Get, requestUrl); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", usertoken.accessToken); response = await client.SendAsync(request); responseString = await response.Content.ReadAsStringAsync(); Models.AzureRMWebCertificates.AzureRMWebCertificates azureRMWebCertificates = JsonConvert.DeserializeObject <Models.AzureRMWebCertificates.AzureRMWebCertificates>(responseString); foreach (Models.AzureRMWebCertificates.Value wsc in azureRMWebCertificates.value) { appServiceCertificate.KeyVaultSecretName = wsc.properties.keyVaultSecretName; appServiceCertificate.CertificateName = wsc.properties.subjectName; appServiceCertificate.KeyVaultId = wsc.properties.keyVaultId; appServiceCertificate.CertificateIssuer = wsc.properties.issuer; appServiceCertificate.CertificateExpiration = wsc.properties.expirationDate; appServiceCertificate.CertificateThumbprint = wsc.properties.thumbprint; appServiceCertificate.CertificateHostnames = wsc.properties.hostNames; } appServiceCertificates.appServiceCertificates.Add(appServiceCertificate); } } return(View(appServiceCertificates)); } }
internal static AppServiceCertificateOrderData DeserializeAppServiceCertificateOrderData(JsonElement element) { Optional <string> kind = default; IDictionary <string, string> tags = default; AzureLocation location = default; ResourceIdentifier id = default; string name = default; ResourceType type = default; SystemData systemData = default; Optional <IDictionary <string, AppServiceCertificate> > certificates = default; Optional <string> distinguishedName = default; Optional <string> domainVerificationToken = default; Optional <int> validityInYears = default; Optional <int> keySize = default; Optional <CertificateProductType> productType = default; Optional <bool> autoRenew = default; Optional <ProvisioningState> provisioningState = default; Optional <CertificateOrderStatus> status = default; Optional <CertificateDetails> signedCertificate = default; Optional <string> csr = default; Optional <CertificateDetails> intermediate = default; Optional <CertificateDetails> root = default; Optional <string> serialNumber = default; Optional <DateTimeOffset> lastCertificateIssuanceTime = default; Optional <DateTimeOffset> expirationTime = default; Optional <bool> isPrivateKeyExternal = default; Optional <IReadOnlyList <AppServiceCertificateNotRenewableReason> > appServiceCertificateNotRenewableReasons = default; Optional <DateTimeOffset> nextAutoRenewalTimeStamp = default; Optional <CertificateOrderContact> contact = default; foreach (var property in element.EnumerateObject()) { if (property.NameEquals("kind")) { kind = property.Value.GetString(); continue; } if (property.NameEquals("tags")) { Dictionary <string, string> dictionary = new Dictionary <string, string>(); foreach (var property0 in property.Value.EnumerateObject()) { dictionary.Add(property0.Name, property0.Value.GetString()); } tags = dictionary; continue; } if (property.NameEquals("location")) { location = property.Value.GetString(); continue; } if (property.NameEquals("id")) { id = new ResourceIdentifier(property.Value.GetString()); continue; } if (property.NameEquals("name")) { name = property.Value.GetString(); continue; } if (property.NameEquals("type")) { type = property.Value.GetString(); continue; } if (property.NameEquals("systemData")) { systemData = JsonSerializer.Deserialize <SystemData>(property.Value.ToString()); continue; } if (property.NameEquals("properties")) { if (property.Value.ValueKind == JsonValueKind.Null) { property.ThrowNonNullablePropertyIsNull(); continue; } foreach (var property0 in property.Value.EnumerateObject()) { if (property0.NameEquals("certificates")) { if (property0.Value.ValueKind == JsonValueKind.Null) { property0.ThrowNonNullablePropertyIsNull(); continue; } Dictionary <string, AppServiceCertificate> dictionary = new Dictionary <string, AppServiceCertificate>(); foreach (var property1 in property0.Value.EnumerateObject()) { dictionary.Add(property1.Name, AppServiceCertificate.DeserializeAppServiceCertificate(property1.Value)); } certificates = dictionary; continue; } if (property0.NameEquals("distinguishedName")) { distinguishedName = property0.Value.GetString(); continue; } if (property0.NameEquals("domainVerificationToken")) { domainVerificationToken = property0.Value.GetString(); continue; } if (property0.NameEquals("validityInYears")) { if (property0.Value.ValueKind == JsonValueKind.Null) { property0.ThrowNonNullablePropertyIsNull(); continue; } validityInYears = property0.Value.GetInt32(); continue; } if (property0.NameEquals("keySize")) { if (property0.Value.ValueKind == JsonValueKind.Null) { property0.ThrowNonNullablePropertyIsNull(); continue; } keySize = property0.Value.GetInt32(); continue; } if (property0.NameEquals("productType")) { if (property0.Value.ValueKind == JsonValueKind.Null) { property0.ThrowNonNullablePropertyIsNull(); continue; } productType = property0.Value.GetString().ToCertificateProductType(); continue; } if (property0.NameEquals("autoRenew")) { if (property0.Value.ValueKind == JsonValueKind.Null) { property0.ThrowNonNullablePropertyIsNull(); continue; } autoRenew = property0.Value.GetBoolean(); continue; } if (property0.NameEquals("provisioningState")) { if (property0.Value.ValueKind == JsonValueKind.Null) { property0.ThrowNonNullablePropertyIsNull(); continue; } provisioningState = property0.Value.GetString().ToProvisioningState(); continue; } if (property0.NameEquals("status")) { if (property0.Value.ValueKind == JsonValueKind.Null) { property0.ThrowNonNullablePropertyIsNull(); continue; } status = property0.Value.GetString().ToCertificateOrderStatus(); continue; } if (property0.NameEquals("signedCertificate")) { if (property0.Value.ValueKind == JsonValueKind.Null) { property0.ThrowNonNullablePropertyIsNull(); continue; } signedCertificate = CertificateDetails.DeserializeCertificateDetails(property0.Value); continue; } if (property0.NameEquals("csr")) { csr = property0.Value.GetString(); continue; } if (property0.NameEquals("intermediate")) { if (property0.Value.ValueKind == JsonValueKind.Null) { property0.ThrowNonNullablePropertyIsNull(); continue; } intermediate = CertificateDetails.DeserializeCertificateDetails(property0.Value); continue; } if (property0.NameEquals("root")) { if (property0.Value.ValueKind == JsonValueKind.Null) { property0.ThrowNonNullablePropertyIsNull(); continue; } root = CertificateDetails.DeserializeCertificateDetails(property0.Value); continue; } if (property0.NameEquals("serialNumber")) { serialNumber = property0.Value.GetString(); continue; } if (property0.NameEquals("lastCertificateIssuanceTime")) { if (property0.Value.ValueKind == JsonValueKind.Null) { property0.ThrowNonNullablePropertyIsNull(); continue; } lastCertificateIssuanceTime = property0.Value.GetDateTimeOffset("O"); continue; } if (property0.NameEquals("expirationTime")) { if (property0.Value.ValueKind == JsonValueKind.Null) { property0.ThrowNonNullablePropertyIsNull(); continue; } expirationTime = property0.Value.GetDateTimeOffset("O"); continue; } if (property0.NameEquals("isPrivateKeyExternal")) { if (property0.Value.ValueKind == JsonValueKind.Null) { property0.ThrowNonNullablePropertyIsNull(); continue; } isPrivateKeyExternal = property0.Value.GetBoolean(); continue; } if (property0.NameEquals("appServiceCertificateNotRenewableReasons")) { if (property0.Value.ValueKind == JsonValueKind.Null) { property0.ThrowNonNullablePropertyIsNull(); continue; } List <AppServiceCertificateNotRenewableReason> array = new List <AppServiceCertificateNotRenewableReason>(); foreach (var item in property0.Value.EnumerateArray()) { array.Add(new AppServiceCertificateNotRenewableReason(item.GetString())); } appServiceCertificateNotRenewableReasons = array; continue; } if (property0.NameEquals("nextAutoRenewalTimeStamp")) { if (property0.Value.ValueKind == JsonValueKind.Null) { property0.ThrowNonNullablePropertyIsNull(); continue; } nextAutoRenewalTimeStamp = property0.Value.GetDateTimeOffset("O"); continue; } if (property0.NameEquals("contact")) { if (property0.Value.ValueKind == JsonValueKind.Null) { property0.ThrowNonNullablePropertyIsNull(); continue; } contact = CertificateOrderContact.DeserializeCertificateOrderContact(property0.Value); continue; } } continue; } } return(new AppServiceCertificateOrderData(id, name, type, systemData, tags, location, kind.Value, Optional.ToDictionary(certificates), distinguishedName.Value, domainVerificationToken.Value, Optional.ToNullable(validityInYears), Optional.ToNullable(keySize), Optional.ToNullable(productType), Optional.ToNullable(autoRenew), Optional.ToNullable(provisioningState), Optional.ToNullable(status), signedCertificate.Value, csr.Value, intermediate.Value, root.Value, serialNumber.Value, Optional.ToNullable(lastCertificateIssuanceTime), Optional.ToNullable(expirationTime), Optional.ToNullable(isPrivateKeyExternal), Optional.ToList(appServiceCertificateNotRenewableReasons), Optional.ToNullable(nextAutoRenewalTimeStamp), contact.Value)); }
// POST: /AppServiceCertificate/ReplaceCertificate public async Task <ActionResult> ReplaceCertificate(AppServiceCertificate ascModel, string authError) { OAuthTokenSet usertoken = new OAuthTokenSet(); HttpClient client = null; // If we have a replacement cert passed to us, persist that to the database. if (Request.HttpMethod == HttpMethod.Post.Method) { ascStore.appServiceCertificates.Add(ascModel); ascStore.SaveChanges(); } string responseString = null; string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier").Value; Uri redirectUri = new Uri(Request.Url.GetLeftPart(UriPartial.Authority).ToString() + "/OAuth"); string state = GenerateState(userObjectID, Request.Url.ToString()); string msoauthUri = string.Format("{0}/oauth2/authorize?resource={1}&client_id={2}&response_type=code&redirect_uri={3}&state={4}", Startup.Authority, Url.Encode(Startup.keyVaultResourceUrl), Startup.clientId, Url.Encode(redirectUri.ToString()), state); ViewBag.AuthorizationUrl = msoauthUri; IEnumerable <OAuthTokenSet> query = from OAuthTokenSet in model.OAuthTokens where OAuthTokenSet.userId == userObjectID && OAuthTokenSet.resourceName == Startup.keyVaultResourceUrl select OAuthTokenSet; if (query.GetEnumerator().MoveNext() == false) { usertoken.state = state; usertoken.userId = userObjectID; usertoken.resourceName = Startup.keyVaultResourceUrl; model.OAuthTokens.Add(usertoken); await model.SaveChangesAsync(); authError = "AuthorizationRequired"; ViewBag.Error = "AuthorizationRequiredKV"; return(View(ascModel)); } else { usertoken = query.First(); authError = null; // If we were redirected here back from the OAuth /authorization endpoint // we need to redisplay the form instead of just processing the request. if (Request.HttpMethod == HttpMethod.Get.Method) { IEnumerable <AppServiceCertificate> cquery = from AppServiceCertificate in ascStore.appServiceCertificates where AppServiceCertificate.Replace == true select AppServiceCertificate; return(View(cquery.First())); } } string kvname = ascModel.ReplacementName.Replace('.', '-'); string requestUrl = String.Format( CultureInfo.InvariantCulture, Startup.keyVaultCreateCertificateUrl, Startup.keyVaultName, kvname); KeyVaultRequest keyVaultRequest = new KeyVaultRequest(); keyVaultRequest.policy = new Models.KeyVault.Policy(); keyVaultRequest.policy.x509_props = new X509_Props(); keyVaultRequest.policy.x509_props.subject = String.Format("CN={0}", ascModel.ReplacementName); string postData = JsonConvert.SerializeObject(keyVaultRequest); System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); byte[] bytes = encoding.GetBytes(postData); client = new HttpClient(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", usertoken.accessToken); request.Content = new ByteArrayContent(bytes); request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); HttpResponseMessage resp = await client.SendAsync(request); if (resp.StatusCode != HttpStatusCode.Accepted) { ViewBag.Error = "unauthorized"; AppServiceCertificates ascs = new AppServiceCertificates(); ascs.appServiceCertificates.Add(ascModel); return(RedirectToAction("Index", "AppServiceCertificate")); } else { } responseString = await resp.Content.ReadAsStringAsync(); dynamic result = JsonConvert.DeserializeObject <dynamic>(responseString); // Working with dynamic type here so I don't have to import all the object model definitions // for each type returned by the KeyVault REST API. KeyVaultRequestResponse kvResponse = new KeyVaultRequestResponse(); foreach (var item in result) { if (item.Name == "csr") { kvResponse.csr = item.Value; } if (item.Name == "id") { kvResponse.id = item.Value; } if (item.Name == "request_id") { kvResponse.requestID = item.Value; } } // Submit CSR to Condor service string zoneinfo = "fee52da0-0b58-11e8-af01-13126b5652e8"; WebApp.Models.Condor.CertificateSigningRequest req = new Models.Condor.CertificateSigningRequest(); req.certificateSigningRequest = kvResponse.getCSRWithHeaders(); req.zoneId = zoneinfo; JsonSerializerSettings serializerSettings = new JsonSerializerSettings(); serializerSettings.NullValueHandling = NullValueHandling.Ignore; postData = JsonConvert.SerializeObject(req, serializerSettings); encoding = new System.Text.ASCIIEncoding(); bytes = encoding.GetBytes(postData); client = new HttpClient(); request = new HttpRequestMessage(HttpMethod.Post, String.Format("{0}/v1/certificaterequests", condorURL)); request.Headers.Add("tppl-api-key", condorAPIKey); request.Content = new ByteArrayContent(bytes); request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); resp = await client.SendAsync(request); // Now poll Condor API to wait for cert to be issued, then install in KeyVault by merging // with previously created request. responseString = await resp.Content.ReadAsStringAsync(); JsonConverter converter = new CondorCertReqConverter(); WebApp.Models.Condor.CertificateSigningRequest certreqresp = JsonConvert.DeserializeObject <Models.Condor.CertificateSigningRequest>(responseString, converter); bool wait = true; while (wait) { client = new HttpClient(); request = new HttpRequestMessage(HttpMethod.Get, String.Format("{0}/v1/certificaterequests/{1}", condorURL, certreqresp.id)); request.Headers.Add("tppl-api-key", condorAPIKey); resp = await client.SendAsync(request); responseString = await resp.Content.ReadAsStringAsync(); certreqresp = JsonConvert.DeserializeObject <Models.Condor.CertificateSigningRequest>(responseString, converter); if (certreqresp.status == "ISSUED") { wait = false; } System.Threading.Thread.Sleep(5000); } string status = certreqresp.status; return(RedirectToAction("Index", "AppServiceCertificate")); }