locked
Azure Active Directory and WCF authentication RRS feed

  • Question

  • I have WCF service and I need to secure it with Azure Active Directory. I've already read all related questions here and at social.msdn but still can't get my sample working. I want authentication to work in following way.

    1. No any popups displayed when user calls WCF service from client.
    2. User passes username/password and receives auth token from Azure ADFS
    3. Then in application (let it be console app for now) we open channel via Create CreateChannelWithIssuedToken method and all subsequent calls are made with the token we get from AAD.

    What I'm doing and what my problems are. I'm for now using VS 2012 and Identity and Access tool to generate proper config file for the WCF service. So my service has following address. http://localhost:1785/Service1.svc

    I go to azure portal and create new Web application with name http://localhost:1785/Service1.svc, sign on url http://localhost:1785/Service1.svc and app id url http://localhost:1785/Service1.svc

    Then I check endpoints of the application and copy federation metadata which looks as https://login.windows.net/{some guid}/federationmetadata/2007-06/federationmetadata.xml

    Using Identity and Access tools I add WAAD Identity provider to the Service project. My web.config file looks as below:

    <?xml version="1.0"?>
    <configuration>
      <configSections>
        <section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
      </configSections>
      <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
        <add key="ida:FederationMetadataLocation" value="https://login.windows.net/34bb8966-5537-4b1b-85ed-f501a06c1225/federationmetadata/2007-06/federationmetadata.xml" />
        <add key="ida:ProviderSelection" value="productionSTS" />
      </appSettings>
      <location path="FederationMetadata">
        <system.web>
          <authorization>
            <allow users="*" />
          </authorization>
        </system.web>
      </location>
      <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5" />
      </system.web>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
              <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
              <serviceDebug includeExceptionDetailInFaults="false" />
              <serviceCredentials useIdentityConfiguration="true">
                <!--Certificate added by Identity and Access Tool for Visual Studio.-->
                <serviceCertificate findValue="CN=localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectDistinguishedName" />
              </serviceCredentials>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <protocolMapping>
          <add scheme="http" binding="ws2007FederationHttpBinding" />
          <add binding="basicHttpsBinding" scheme="https" />
        </protocolMapping>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
        <bindings>
          <ws2007FederationHttpBinding>
            <binding name="">
              <security mode="Message">
                <message>
                  <issuerMetadata address="https://login.windows.net/adfs/services/trust/mex" />
                </message>
              </security>
            </binding>
          </ws2007FederationHttpBinding>
        </bindings>
      </system.serviceModel>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true" />
        <!--
            To browse web app root directory during debugging, set the value below to true.
            Set to false before deployment to avoid disclosing web app folder information.
          -->
        <directoryBrowse enabled="true" />
      </system.webServer>
      <system.identityModel>
        <identityConfiguration>
          <audienceUris>
            <add value="http://localhost:1785/Service1.svc" />
          </audienceUris>
          <issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
            <authority name="https://sts.windows.net/34bb8966-5537-4b1b-85ed-f501a06c1225/">
              <keys>
                <add thumbprint="92B88C3DD981BF1EBCB244FCFA63C007706C79E0" />
                <add thumbprint="3270BF5597004DF339A4E62224731B6BD82810A6" />
              </keys>
              <validIssuers>
                <add name="https://sts.windows.net/34bb8966-5537-4b1b-85ed-f501a06c1225/" />
              </validIssuers>
            </authority>
          </issuerNameRegistry>
          <!--certificationValidationMode set to "None" by the the Identity and Access Tool for Visual Studio. For development purposes.-->
          <certificateValidation certificateValidationMode="None" />
        </identityConfiguration>
      </system.identityModel>
    </configuration>

    Then I created console application and added service reference to the service project. After adding reference, config looks as

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <startup> 
            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
        </startup>
        <system.serviceModel>
            <bindings>
                <ws2007FederationHttpBinding>
                    <binding name="WS2007FederationHttpBinding_IService1">
                        <security>
                            <message>
                                <!--<issuer address="http://schemas.microsoft.com/2005/12/ServiceModel/Addressing/Anonymous" />-->
                              <issuer address="https://login.windows.net/34bb8966-5537-4b1b-85ed-f501a06c1225/wsfed" binding="ws2007HttpBinding"/>
                              <issuerMetadata address="https://login.windows.net/adfs/services/trust/mex" />
                                <tokenRequestParameters>
                                    <trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
                                        <trust:KeyType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</trust:KeyType>
                                        <trust:KeySize xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">256</trust:KeySize>
                                        <trust:KeyWrapAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p</trust:KeyWrapAlgorithm>
                                        <trust:EncryptWith xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptWith>
                                        <trust:SignWith xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2000/09/xmldsig#hmac-sha1</trust:SignWith>
                                        <trust:CanonicalizationAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/10/xml-exc-c14n#</trust:CanonicalizationAlgorithm>
                                        <trust:EncryptionAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptionAlgorithm>
                                    </trust:SecondaryParameters>
                                </tokenRequestParameters>
                            </message>
                        </security>
                    </binding>
                </ws2007FederationHttpBinding>
                <ws2007HttpBinding>
                    <binding name="">
                        <security mode="TransportWithMessageCredential">
                            <transport clientCredentialType="InheritedFromHost" />
                            <message establishSecurityContext="false" />
                        </security>
                    </binding>
                </ws2007HttpBinding>
            </bindings>
            <client>
                <endpoint address="http://localhost:1785/Service1.svc" binding="ws2007FederationHttpBinding"
                    bindingConfiguration="WS2007FederationHttpBinding_IService1"
                    contract="SomeService.IService1" name="WS2007FederationHttpBinding_IService1">
                    <identity>
                        <certificate encodedValue="AwAAAAEAAAAUAAAACLf4gntwdBYHCTmyInF5gU9oXNYgAAAAAQAAANUBAAAwggHRMIIBOqADAgECAhAT1EWwzeLBk0ez5Bg+JKyVMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xMjExMTUxNTMyMDdaFw0xNzExMTUwMDAwMDBaMBQxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtgkwd4GLTIwRtoHFjoSCBqrEcFgYMPh7f8aSWSYTrBGtaS9c2zOAuhxnaIAo1ELe3JLWUJmHq35IEu34gTwN9RfSna9Gis45TKrINY5nlAmKu0XpuI3ncf4WQRPbPx7hS6A0BHytXqQ3+FA1BSRr13iNUaaAkqwcCLWHXqno188CAwEAAaMkMCIwCwYDVR0PBAQDAgSwMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4GBACKXEQpUUVm1g3BfpqRSn9hIYpuLojPX2wfySbIAan4jK5oo0dC5QUkbRjyEtqe6Io+POL3gbtoVzJOXnUDvYDUXRaR6dUmHJ5A4JLChUJZLHis0resLKO5yXrf4JqJSwEsL4Et5xiIRPoEvdPWWBhkDwuMvDGtQrzpp6ZYEt2sh" />
                    </identity>
                </endpoint>
            </client>
        </system.serviceModel>
    </configuration>

    I tried to launch console application, but the error that valid issue should be specified has raised. So I thought, that valid issue can be found in endpoints at Azure AD configuration page, and copied WS-Federation Single sign-on endpoint as an issuer.

    Console program code is below.

    var client = new SomeService.Service1Client();
                client.ClientCredentials.UserName.UserName = "<valid user name>";
                client.ClientCredentials.UserName.Password = "<password>";
                client.GetData(10);

    When I call service, I see in fiddler, that request is sent to WS-Fed endpoint but in response endpoint sends me html page with error

    AADSTS20012: An error occurred when we tried to process a WS-Federation message. The message was invalid.

    Could you please suggest me where I'm wrong and what to do to implement scenario I described in the beginning of the question? Thanks.

    Friday, November 14, 2014 1:08 PM

Answers

All replies

  • Hi Oleg,

    Thanks for posting here!

    AADSTS20012 - With the error message provided above I presume that it could be an issue with the portal as mentioned in this thread link.

    Just to make sure you have followed the steps correctly and there is no miss on it, refer this link - http://blogs.msdn.com/b/brunoterkaly/archive/2014/04/01/exercise-3-securing-a-wcf-service-using-windows-azure-active-directory.aspx

    You might also want to check this reference link - http://msdn.microsoft.com/en-us/library/ff647503.aspx

    A similar scenario reference - http://stackoverflow.com/questions/16403426/azure-wcf-service-with-azure-active-directory-authentication

    Hope this helps!

    Let me know if you have any queries!

    Best Regards,

    Sadiqh Ahmed

    Disclaimer: This response contains a reference to a third party World Wide Web site.
    Microsoft is providing this information as a convenience to you. Microsoft does not control these sites and has not tested any software or information found on these sites; therefore, Microsoft cannot make any representations regarding the quality, safety, or suitability of any software or information found there.
    There are inherent dangers in the use of any software found on the Internet, and Microsoft cautions you to make sure that you completely understand the risk before retrieving any software from the Internet.

    Friday, November 14, 2014 4:21 PM
  • Thank you, Sadiqh.

    I've already visited all the links you suggested, before posting to the forum.

    Let me clarify the question a little.

    I'm not sure, that I use correct issuer address. Because one that is generated for our local ADFS service is

    https://<adfs address>/adfs/services/trust/13/usernamemixed.

    Could you please either confirm that

    https://login.windows.net/34bb8966-5537-4b1b-85ed-f501a06c1225/wsfed

    is correct as issuer address, or point me to valid address for Azure Active Directory ADFS.

    Thanks.

    Friday, November 14, 2014 4:39 PM
  • Hi Oleg,

    We are looking into this issue. Would require sometime to assist you with the right answer.

    We shall update this thread with our findings shortly.

    Thanks,

    Sadiqh Ahmed

    Monday, November 17, 2014 8:02 PM
  • Sadiqh, thanks a lot. Any help would be appreciated.

    Meanwhile, I have another question that is related to the topic, so I'm asking it here.

    Does Azure Active Directory ADFS support active client authorization?

    I mean is it possible to get auth token just by passing login/password to Azure ADFS in any way, without opening browser and switching to passive mode?

    Thanks.

    Tuesday, November 18, 2014 11:00 AM
  • Unfortunately, WCF uses WS-Trust which is not supported by Azure AD.
    Friday, November 21, 2014 10:51 PM
  • I'm marking the above post as answer. Please write back or create a new forum post if you need further assistance.

    Regards,

    Sadiqh Ahmed

    Friday, November 28, 2014 7:23 PM