Экспорт (0) Печать
Развернуть все

Delete Service Certificate

Обновлено: Апрель 2014 г.

The Delete Service Certificate asynchronous operation deletes a service certificate from the certificate store of a cloud service.

The Delete Service Certificate request may be specified as follows. Replace <subscription-id> with the subscription ID, <service-name> with the DNS prefix name of the cloud service, <thumbprint-algorithm> with the algorithm for the thumbprint, and <thumbprint> with the thumbprint.

 

Method Request URI

DELETE

https://management.core.windows.net/<subscription-id>/services/hostedservices/<service-name>/certificates/<thumbprint-algorithm>-<thumbprint>

You must make sure that the request that is made to the management service is secure. For additional details, see Authenticating Service Management Requests.

The following table describes the request headers.

 

Request Header Description

x-ms-version

Required. Specifies the version of the operation to use for this request. This header should be set to 2009-10-01 or higher. For more information about versioning headers, see Работа с версиями при управлении службами.

The response includes an HTTP status code and a set of response headers.

A successful operation returns status code 200 (OK). For information about status codes, see Service Management Status and Error Codes.

The response for this operation includes the following headers. The response may also include additional standard HTTP headers. All standard headers comply with the HTTP/1.1 protocol specification.

 

Response Header Description

x-ms-request-id

A value that uniquely identifies a request made against the management service. For an asynchronous operation, you can call Get Operation Status with the value of the header to determine whether the operation is complete, has failed, or is still in progress.

The following example is a console program that adds a pfx certificate to a specified cloud service, and then deletes the certificate from the cloud service. To run the example, create a service certificate and save it with its private key as a pfx file in your Documents folder. When you create the service certificate as a pfx file, give it a password that you will enter later to add the certificate to your cloud service. Modify the code to update the Version string with the desired value to use in the x-ms-version header. Set the ManagementThumbprint value to the thumbprint of your management certificate. Set the SubscriptionId value to the subscription identifier, and set the ServiceName to the DNS prefix name of your hosted service. Set the PfxFile value to the name of the service certificate pfx file, and set the CertificateThumbprint value to the thumbprint of the certificate. When the program runs, it requests the password for the service certificate pfx file. Then it uses the Add Service Certificate operation to add the certificate to the cloud service, and polls for the asynchronous result using the Get Operation Status operation. When the result is available, the program uses the List Service Certificates operation to display the certificates in the cloud service. Then it uses the Delete Service Certificate operation to delete the certificate from the cloud service, and polls for the asynchronous result using the Get Operation Status operation. Finally, it uses the List Service Certificates operation to show that the certificate has been removed. See Создание сертификата службы для Windows Azure for more information about how to create a certificate, export it as a .pfx file, and obtain its thumbprint.

namespace Microsoft.WindowsAzure.ServiceManagementRESTAPI.Samples
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    using System.Threading;
    using System.Xml;
    using System.Xml.Linq;
 
    public class Program
    {
        // Set these constants with your values to run the sample.
        private const string XMsVersion = "2011-10-01";
        private const string ManagementThumbprint = "management-certificate-thumbprint";
        private const string SubscriptionId = "subscription-identifier";
        private const string ServiceName = "service-dns-prefix-name";
        private const string PfxFile = "service-certificate-pfx-file";
        private const string CertificateThumbprint = "service-certificate-thumbprint";
 
        // This is the common namespace for all Service Management REST API XML data.
        private static XNamespace wa = "http://schemas.microsoft.com/windowsazure";
 
        /// <summary>
        /// The operation status values from PollGetOperationStatus.
        /// </summary>
        private enum OperationStatus
        {
            InProgress,
            Failed,
            Succeeded,
            TimedOut
        }
 
        /// <summary>
        /// Gets or sets the management certificate for subscription access.
        /// </summary>
        private static X509Certificate2 ManagementCertificate { get; set; }
 
        static void Main(string[] args)
        {
            try
            {
                ManagementCertificate = GetStoreCertificate(ManagementThumbprint);
 
                // Add a certificate from a particular PFX file in the users
                // documents folder:
                string certificatePath = Path.Combine(
                    Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
                    PfxFile);
                string certificateData = Convert.ToBase64String(
                    File.ReadAllBytes(certificatePath));
 
                Console.Write("Enter the password for {0}: ", PfxFile);
                string pfxPassword = Console.ReadLine();
 
                string requestId = AddCertificate(
                    ServiceName,
                    certificateData,
                    pfxPassword);
                Console.WriteLine(
                    "Called Add Certificate operation: requestId {0}",
                    requestId);
 
                // Loop on Get Operation Status for result of add certificate
                OperationResult result = PollGetOperationStatus(
                    requestId,
                    pollIntervalSeconds: 20,
                    timeoutSeconds: 180);
                DisplayOperationResult(requestId, result);
 
                // Display the certificates for the hosted service.
                XElement certificates = ListCertificates(ServiceName);
                Console.WriteLine(
                    "Certificates for Hosted Service {0}:{1}{2}",
                    ServiceName,
                    Environment.NewLine,
                    certificates.ToString(SaveOptions.OmitDuplicateNamespaces));
                
                // Now delete the added certificate
                requestId = DeleteCertificate(
                    ServiceName,
                    "sha1",
                    CertificateThumbprint);
                Console.WriteLine(
                    "Called Delete Certificate operation: requestId {0}",
                    requestId);
 
                // Loop on Get Operation Status for result of delete certificate
                result = PollGetOperationStatus(
                    requestId,
                    pollIntervalSeconds: 20,
                    timeoutSeconds: 180);
                DisplayOperationResult(requestId, result);
 
                // Display the certificates for the hosted service.
                certificates = ListCertificates(ServiceName);
                Console.WriteLine(
                    "Certificates for Hosted Service {0}:{1}{2}",
                    ServiceName,
                    Environment.NewLine,
                    certificates.ToString(SaveOptions.OmitDuplicateNamespaces));
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception caught in Main:");
                Console.WriteLine(ex.Message);
            }
 
            Console.Write("Press any key to continue:");
            Console.ReadKey();
        }
 
        private static void DisplayOperationResult(
            string requestId, 
            OperationResult result)
        {
            switch (result.Status)
            {
                case OperationStatus.TimedOut:
                    Console.WriteLine(
                        "Poll of Get Operation Status timed out: " +
                        "Operation {0} is still in progress after {1} seconds.",
                        requestId,
                        (int)result.RunningTime.TotalSeconds);
                    break;
 
                case OperationStatus.Failed:
                    Console.WriteLine(
                        "Failed: Operation {0} failed after " +
                        "{1} seconds with status {2} ({3}) - {4}: {5}",
                        requestId,
                        (int)result.RunningTime.TotalSeconds,
                        (int)result.StatusCode,
                        result.StatusCode,
                        result.Code,
                        result.Message);
                    break;
 
                case OperationStatus.Succeeded:
                    Console.WriteLine(
                        "Succeeded: Operation {0} completed " +
                        "after {1} seconds with status {2} ({3})",
                        requestId,
                        (int)result.RunningTime.TotalSeconds,
                        (int)result.StatusCode,
                        result.StatusCode);
                    break;
            }
        }
 
        /// <summary>
        /// Calls the asynchronous Add Certificate operation in the Service 
        /// Management REST API to add a certificate to a hosted service. 
        /// Use the returned request ID value with the Get Operation Status 
        /// operation to get the final result of this operation.
        /// </summary>
        /// <param name="serviceName">The DNS prefix name of the hosted service to add the certificate to.</param>
        /// <param name="certificateData">The base-64 encoded contents of the .PFX file containing the certificate data.</param>
        /// <param name="password">The password to access the .PFX certificate data.</param>
        /// <returns>The request ID for use with Get Operation Status.</returns>
        private static string AddCertificate(
            string serviceName,
            string certificateData,
            string password)
        {
            string uriFormat = "https://management.core.windows.net/{0}" +
                "/services/hostedservices/{1}/certificates";
            Uri uri = new Uri(String.Format(uriFormat, SubscriptionId, serviceName));
 
            // Create the request XML document
            XDocument requestBody = new XDocument(
                new XDeclaration("1.0", "UTF-8", "no"),
                new XElement(
                    wa + "CertificateFile",
                    new XElement(wa + "Data", certificateData),
                    new XElement(wa + "CertificateFormat", "pfx"),
                    new XElement(wa + "Password", password)));
 
            XDocument responseBody;
            return InvokeRequest(
                uri, "POST", HttpStatusCode.Accepted, requestBody, out responseBody);
        }
 
        /// <summary>
        /// Calls the asynchronous Delete Certificate operation in the Service 
        /// Management REST API to remove a certificate from a hosted service. 
        /// Use the returned request ID value with the Get Operation Status 
        /// operation to get the final result of this operation.
        /// </summary>
        /// <param name="serviceName">The DNS prefix name of the hosted service to remove the certificate from.</param>
        /// <param name="algorithm">The algorithm of the certificate to delete, for example, "sha1".</param>
        /// <param name="thumbprint">The thumbprint for the certificate to delete.</param>
        /// <returns>The request ID for use with Get Operation Status.</returns>
        private static string DeleteCertificate(
            string serviceName,
            string algorithm,
            string thumbprint)
        {
            string uriFormat = "https://management.core.windows.net/{0}" +
                    "/services/hostedservices/{1}/certificates/{2}-{3}";
            Uri uri = new Uri(String.Format(
                uriFormat, SubscriptionId, serviceName, algorithm, thumbprint));
 
            XDocument responseBody;
            return InvokeRequest(
                uri, "DELETE", HttpStatusCode.Accepted, null, out responseBody);
        }
 
        /// <summary>
        /// Calls the List Certificates operation in the Service Management 
        /// REST API for the specified subscription and hosted service, and 
        /// returns the Certificates XML element from the response.
        /// </summary>
        /// <param name="serviceName">The DNS prefix name of the hosted service to list certificates for.</param>
        /// <returns>The HostedServices XML element from the response.</returns>
        private static XElement ListCertificates(
            string serviceName)
        {
            string uriFormat = "https://management.core.windows.net/{0}" +
                "/services/hostedservices/{1}/certificates";
            Uri uri = new Uri(String.Format(uriFormat, SubscriptionId, serviceName));
            XDocument responseBody;
            InvokeRequest(uri, "GET", HttpStatusCode.OK, null, out responseBody);
            return responseBody.Element(wa + "Certificates");
        }
 
        /// <summary>
        /// Calls the Get Operation Status operation in the Service 
        /// Management REST API for the specified subscription and requestId 
        /// and returns the Operation XML element from the response.
        /// </summary>
        /// <param name="requestId">The requestId of the operation to track.</param>
        /// <returns>The Operation XML element from the response.</returns>
        private static XElement GetOperationStatus(
            string requestId)
        {
            string uriFormat = "https://management.core.windows.net/{0}" +
                "/operations/{1}";
            Uri uri = new Uri(String.Format(uriFormat, SubscriptionId, requestId));
            XDocument responseBody;
            InvokeRequest(uri, "GET", HttpStatusCode.OK, null, out responseBody);
            return responseBody.Element(wa + "Operation");
        }
 
        /// <summary>
        /// The results from PollGetOperationStatus are passed in this struct.
        /// </summary>
        private struct OperationResult
        {
            // The status: InProgress, Failed, Succeeded, or TimedOut.
            public OperationStatus Status { get; set; }
 
            // The http status code of the requestId operation, if any.
            public HttpStatusCode StatusCode { get; set; }
 
            // The approximate running time for PollGetOperationStatus.
            public TimeSpan RunningTime { get; set; }
 
            // The error code for the failed operation.
            public string Code { get; set; }
 
            // The message for the failed operation.
            public string Message { get; set; }
        }
 
        /// <summary>
        /// Polls Get Operation Status for the operation specified by requestId
        /// every pollIntervalSeconds until timeoutSeconds have passed or the
        /// operation has returned a Failed or Succeeded status. 
        /// </summary>
        /// <param name="requestId">The requestId of the operation to get status for.</param>
        /// <param name="pollIntervalSeconds">The interval between calls to Get Operation Status.</param>
        /// <param name="timeoutSeconds">The maximum number of seconds to poll.</param>
        /// <returns>An OperationResult structure with status or error information.</returns>
        private static OperationResult PollGetOperationStatus(
            string requestId,
            int pollIntervalSeconds,
            int timeoutSeconds)
        {
            OperationResult result = new OperationResult();
            DateTime beginPollTime = DateTime.UtcNow;
            TimeSpan pollInterval = new TimeSpan(0, 0, pollIntervalSeconds);
            DateTime endPollTime = beginPollTime + new TimeSpan(0, 0, timeoutSeconds);
 
            bool done = false;
            while (!done)
            {
                XElement operation = GetOperationStatus(requestId);
                result.RunningTime = DateTime.UtcNow - beginPollTime;
                try
                {
                    // Turn the Status string into an OperationStatus value
                    result.Status = (OperationStatus)Enum.Parse(
                        typeof(OperationStatus),
                        operation.Element(wa + "Status").Value);
                }
                catch (Exception e)
                {
                    throw new ApplicationException(string.Format(
                        "Get Operation Status {0} returned unexpected status: {1}{2}",
                        requestId,
                        Environment.NewLine,
                        operation.ToString(SaveOptions.OmitDuplicateNamespaces)),
                        e);
                }
 
                switch (result.Status)
                {
                    case OperationStatus.InProgress:
                        Console.WriteLine(
                            "In progress for {0} seconds",
                            (int)result.RunningTime.TotalSeconds);
                        Thread.Sleep((int)pollInterval.TotalMilliseconds);
                        break;
 
                    case OperationStatus.Failed:
                        result.StatusCode = (HttpStatusCode)Convert.ToInt32(
                            operation.Element(wa + "HttpStatusCode").Value);
                        XElement error = operation.Element(wa + "Error");
                        result.Code = error.Element(wa + "Code").Value;
                        result.Message = error.Element(wa + "Message").Value;
                        done = true;
                        break;
 
                    case OperationStatus.Succeeded:
                        result.StatusCode = (HttpStatusCode)Convert.ToInt32(
                            operation.Element(wa + "HttpStatusCode").Value);
                        done = true;
                        break;
                }
 
                if (!done && DateTime.UtcNow > endPollTime)
                {
                    result.Status = OperationStatus.TimedOut;
                    done = true;
                }
            }
 
            return result;
        }
 
        /// <summary>
        /// Gets the certificate matching the thumbprint from the local store.
        /// Throws an ArgumentException if a matching certificate is not found.
        /// </summary>
        /// <param name="thumbprint">The thumbprint of the certificate to find.</param>
        /// <returns>The certificate with the specified thumbprint.</returns>
        private static X509Certificate2 GetStoreCertificate(string thumbprint)
        {
            List<StoreLocation> locations = new List<StoreLocation> 
            { 
                StoreLocation.CurrentUser, 
                StoreLocation.LocalMachine 
            };
 
            foreach (var location in locations)
            {
                X509Store store = new X509Store("My", location);
                try
                {
                    store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                    X509Certificate2Collection certificates = store.Certificates.Find(
                        X509FindType.FindByThumbprint, thumbprint, false);
                    if (certificates.Count == 1)
                    {
                        return certificates[0];
                    }
                }
                finally
                {
                    store.Close();
                }
            }
 
            throw new ArgumentException(string.Format(
                "A Certificate with thumbprint '{0}' could not be located.",
                thumbprint));
        }
 
        /// <summary>
        /// A helper function to invoke a Service Management REST API operation.
        /// Throws an ApplicationException on unexpected status code results.
        /// </summary>
        /// <param name="uri">The URI of the operation to invoke using a web request.</param>
        /// <param name="method">The method of the web request, GET, PUT, POST, or DELETE.</param>
        /// <param name="expectedCode">The expected status code.</param>
        /// <param name="requestBody">The XML body to send with the web request. Use null to send no request body.</param>
        /// <param name="responseBody">The XML body returned by the request, if any.</param>
        /// <returns>The requestId returned by the operation.</returns>
        private static string InvokeRequest(
            Uri uri,
            string method,
            HttpStatusCode expectedCode,
            XDocument requestBody,
            out XDocument responseBody)
        {
            responseBody = null;
            string requestId = String.Empty;
 
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
            request.Method = method;
            request.Headers.Add("x-ms-Version", XMsVersion);
            request.ClientCertificates.Add(ManagementCertificate);
            request.ContentType = "application/xml";
 
            if (requestBody != null)
            {
                using (Stream requestStream = request.GetRequestStream())
                {
                    using (StreamWriter streamWriter = new StreamWriter(
                        requestStream, System.Text.UTF8Encoding.UTF8))
                    {
                        requestBody.Save(streamWriter, SaveOptions.DisableFormatting);
                    }
                }
            }
 
            HttpWebResponse response;
            HttpStatusCode statusCode = HttpStatusCode.Unused;
            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException ex)
            {
                // GetResponse throws a WebException for 4XX and 5XX status codes
                response = (HttpWebResponse)ex.Response;
            }
 
            try
            {
                statusCode = response.StatusCode;
                if (response.ContentLength > 0)
                {
                    using (XmlReader reader = XmlReader.Create(response.GetResponseStream()))
                    {
                        responseBody = XDocument.Load(reader);
                    }
                }
 
                if (response.Headers != null)
                {
                    requestId = response.Headers["x-ms-request-id"];
                }
            }
            finally
            {
                response.Close();
            }
 
            if (!statusCode.Equals(expectedCode))
            {
                throw new ApplicationException(string.Format(
                    "Call to {0} returned an error:{1}Status Code: {2} ({3}):{1}{4}",
                    uri.ToString(),
                    Environment.NewLine,
                    (int)statusCode,
                    statusCode,
                    responseBody.ToString(SaveOptions.OmitDuplicateNamespaces)));
            }
 
            return requestId;
        }
    }
}

The following example output shows the certificate added to the cloud service, and then shows that the cloud service has no certificates after the certificate is deleted:

Enter the password for hostedservicecertificate.pfx: ********
Called Add Certificate operation: requestId fdcf42761fb1424688a5968aa38811d7
In progress for 0 seconds
Succeeded: Operation fdcf42761fb1424688a5968aa38811d7 completed after 21 seconds with status 200 (OK)
Certificates for Hosted Service MyHostedService1:
<Certificates xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Certificate>
    <CertificateUrl>https://management.core.windows.net/01234567-89ab-cdef-0123-456789abcdef/services/hostedservices/MyHostedService1/certificates/sha1-2EA90CBB65EFCF71C92F55363954A16B87941ECD</CertificateUrl>
    <Thumbprint>2EA90CBB65EFCF71C92F55363954A16B87941ECD</Thumbprint>
    <ThumbprintAlgorithm>sha1</ThumbprintAlgorithm>
    <Data>MIIDIDCCAgygAwIBAgIQFacJqSCsGKVGE19GKlrEejAJBgUrDgMCHQUAMCMxITAfBgNVBAMTGGhvc3RlZHNlcnZpY2VjZXJ0aWZpY2F0ZTAeFw0xMTExMTAwMDM3NDRaFw0zOTEyMzEyMzU5NTlaMCMxITAfBgNVBAMTGGhvc3RlZHNlcnZpY2VjZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM94zedfRaAcpOESoStDBM/r18qdOI7HFawK+8sd+atW93L+pJgUjmEYgbHsBET2YZRTWHV2l6HkV7CRnSgTMQ/0SrIsGj+l1BG5Xncdp5Do9dbpHOQmZYVB3t3l0BcFgj3DP+atNXWctUpjdyDJB+USZJB7o0gz3esmyxdD1HaFBu1LW7GfhWHDmC0+QERdoKxAvVKY1wuvCxY1/LdCno6ZMV95l5xJ5jzf/itRo0A9wD5tlcR7bJL7Xp45REKZoaVwxCIooL8fC427LQf2EZbwjhU3kqPOyQ40vNTB+ksJneXqXjhh7Hefond9fFe6O7mwGVfbqOsbFWJsrTA7b40CAwEAAaNYMFYwVAYDVR0BBE0wS4AQMezArIE9mdwqywnNC9Y/NaElMCMxITAfBgNVBAMTGGhvc3RlZHNlcnZpY2VjZXJ0aWZpY2F0ZYIQFacJqSCsGKVGE19GKlrEejAJBgUrDgMCHQUAA4IBAQA0XehZ43Yt/u/NlOSYOkGhCeomndZbBcijGH9fo39OiMPwN1BOY1Ch1YmlTt60o/1u1Lg7oxx9+NfE4O2x2xqBK+SIT/W4gtowjmwFg+dRu0qRCYcJL1HaQWGoRbkZrJHNOKsBVUWJbSKyOtM/MZ2v5eZ2q2imDLNMnIPY6YaeP9s4lLhcu53iuzkHf1JvsmNkvI7XQkCw2W/COu8ndcXmTrhc1btz+j3r6G9siGeRQ+xDV394GIAtTZgszefJXVkjiYlHczUmr0ZPKWh3vA/RTyrcQfDVH0QBZ9CMYNhhI1PIJOPAQ3X5YsYQwah9pbYV4mIXaJKld+eNsEFt3Zo8</Data>
  </Certificate>
</Certificates>
Called Delete Certificate operation: requestId e480c3ffab2a4b7a840730200f004130
Succeeded: Operation e480c3ffab2a4b7a840730200f004130 completed after 0 seconds with status 200 (OK)
Certificates for Hosted Service MyHostedService1:
<Certificates xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
Press any key to continue:

Показ:
© 2014 Microsoft