Ask a questionAsk a question
 

AnswerUsing Service Management API from a Hosted Service

  • Tuesday, November 03, 2009 10:47 AMSarangKulkarni Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    1. I have a hosted service"A" from which I need to access/change configuration in another hosted service "B".

    2. I have uploaded the Certificate to both the Accounts.

    3. I have also uploaded the certificate to a Blob.

    4. I am able to create an instance of X509Certificate2 from the byte array.

    5. However when I use the same instance to create an HttpWebRequest and call the Service Management API i get a "403 Forbidden".

    6. If I try the same thing on a devfab with the certificate installed in the personal Cert store it works like a charm and fails even on the devfab if I remove the certificate from the store.

    What am I doing wrong and What are my options?

Answers

  • Tuesday, November 03, 2009 9:24 PMvbori Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Ignore all the WCF-specific stuff in that post.

    Add a new section to  <configSections> of your web.config:

    <section name="microsoft.identityModelPlus"                    type="Microsoft.IdentityModelPlus.Configuration.MicrosoftIdentityModelPlusSection, Microsoft.IdentityModelPlus" requirePermission="false" />

    Now you need to specify the certificate in web.config. To do that, you can use the CreateCert tool from the Passive Federation example. The output of CreateCert is a file named Encoder.out, which you can literally cut and paste into your web.config and you are done specifying the certificate.

    This is example code to load the certificate, which you can then just add to your HttpWebRequest.

    public static X509Certificate2 GetCertificate()
    {
    MicrosoftIdentityModelPlusSection plusConfiguration = MicrosoftIdentityModelPlusSection.Current;
    X509Certificate2 serviceCertificate = null;
    if (plusConfiguration != null && plusConfiguration.ServiceCertificate.ElementInformation.IsPresent)
    {
    serviceCertificate = plusConfiguration.ServiceCertificate.GetCertificate();
    }
    return serviceCertificate;
    }


    You'll need to modify CreateCert because the one in the Passive Federation Example doesn't generate 2048-bit keys. The script I use is:

    makecert -r -pe -n "CN=%1.cloudapp.net" -sky exchange  -sv %1.cloudapp.net.pvk -len 2048 -a sha1 %1.cloudapp.net.cer

    pvk2pfx -pvk %1.cloudapp.net.pvk -spc %1.cloudapp.net.cer -pfx %1.cloudapp.net.pfx -po abc!123

    "%~dp0\utils\Encoder.exe" %1.cloudapp.net.pfx

    SET capicompath="%PROGRAMFILES%\Microsoft CAPICOM 2.1.0.2 SDK\Samples\vbs\cstore.vbs"
    SET cscript=%windir%\system32\cscript.exe

    %cscript% /nologo %capicompath% import -e -l CU -s MY "%~dp0%1.cloudapp.net.pfx" "abc!123"
    %cscript% /nologo %capicompath% import -e -l CU -s root "%~dp0%1.cloudapp.net.pfx" "abc!123"

    Obviously, you'll have to have all the tools downloaded and in the path (you need to build encoder.exe, download CAPICOM SDK, make sure you have pck2pfx and makecert, etc).

    It's straightforward and it works, but it's obviously a bit painful. Let me know if you still have trouble making it work.

All Replies

  • Tuesday, November 03, 2009 4:59 PMvbori Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    See this thread
    http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/37616ed7-01c3-40ad-97f7-74df9defed53
    and Yi-Lun Luo's suggestions near the bottom. This technique, using the Windows Identity Foundation to load the certificate, works fine. I use it to make programmatic changes to a hosted service deployment's configuration. (I too had tried something similar to your method in the past, with the same results, and it's still not clear to me why that works in the devfab and not online.)

  • Tuesday, November 03, 2009 6:53 PMSarangKulkarni Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Proposed Answer
    @vbori: Thanks for the reply, I am a novice with WCF and am not aware where exactly WCF comes into picture when I am writing a simple asp.net application and calling a REST service.

    Could you kindly elaborate further?

    I did follow the steps nd have a CustomServiceHost and a ustomServiceHost factory in my web role now additionally I have also added the requisite Microsoft.IdentityModelPlus settings to the web.Config.

    • Proposed As Answer byvbori Tuesday, November 03, 2009 9:08 PM
    •  
  • Tuesday, November 03, 2009 9:24 PMvbori Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Ignore all the WCF-specific stuff in that post.

    Add a new section to  <configSections> of your web.config:

    <section name="microsoft.identityModelPlus"                    type="Microsoft.IdentityModelPlus.Configuration.MicrosoftIdentityModelPlusSection, Microsoft.IdentityModelPlus" requirePermission="false" />

    Now you need to specify the certificate in web.config. To do that, you can use the CreateCert tool from the Passive Federation example. The output of CreateCert is a file named Encoder.out, which you can literally cut and paste into your web.config and you are done specifying the certificate.

    This is example code to load the certificate, which you can then just add to your HttpWebRequest.

    public static X509Certificate2 GetCertificate()
    {
    MicrosoftIdentityModelPlusSection plusConfiguration = MicrosoftIdentityModelPlusSection.Current;
    X509Certificate2 serviceCertificate = null;
    if (plusConfiguration != null && plusConfiguration.ServiceCertificate.ElementInformation.IsPresent)
    {
    serviceCertificate = plusConfiguration.ServiceCertificate.GetCertificate();
    }
    return serviceCertificate;
    }


    You'll need to modify CreateCert because the one in the Passive Federation Example doesn't generate 2048-bit keys. The script I use is:

    makecert -r -pe -n "CN=%1.cloudapp.net" -sky exchange  -sv %1.cloudapp.net.pvk -len 2048 -a sha1 %1.cloudapp.net.cer

    pvk2pfx -pvk %1.cloudapp.net.pvk -spc %1.cloudapp.net.cer -pfx %1.cloudapp.net.pfx -po abc!123

    "%~dp0\utils\Encoder.exe" %1.cloudapp.net.pfx

    SET capicompath="%PROGRAMFILES%\Microsoft CAPICOM 2.1.0.2 SDK\Samples\vbs\cstore.vbs"
    SET cscript=%windir%\system32\cscript.exe

    %cscript% /nologo %capicompath% import -e -l CU -s MY "%~dp0%1.cloudapp.net.pfx" "abc!123"
    %cscript% /nologo %capicompath% import -e -l CU -s root "%~dp0%1.cloudapp.net.pfx" "abc!123"

    Obviously, you'll have to have all the tools downloaded and in the path (you need to build encoder.exe, download CAPICOM SDK, make sure you have pck2pfx and makecert, etc).

    It's straightforward and it works, but it's obviously a bit painful. Let me know if you still have trouble making it work.

  • Wednesday, November 04, 2009 6:12 AMSarangKulkarni Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    @vbori: Yup, did the same through the night and it works like a charm. Thanks a tonne!