Publishing CRM Internet Facing Deployment using Web Application Proxy and


If you’ve been following the TMG/UAG product line for a while you’ll know that those products
are end of life.   The official announcement was recently made on the Server & Cloud Blog <http://blogs.technet.com/b/server-cloud/archive/2013/12/17/important-changes-to-the-forefront-product-line.aspx>

I’ve been working on deploying Web Application Proxy with one of my customers recently in an effort to transition them off UAG.   We were successful in getting SharePoint working quickly but we ran into some problems with CRM.   Given how new WAP is I thought it would be appropriate to document what we had to do in order to get it working.

The customer has 3 externally facing URLs that we need to publish via WAP:

https://auth.crm.contoso.com/

https://org.crm.contoso.com/

https://discovery.crm.contoso.com/

 

Additionally WAP and ADFS are published at

https://fs.contoso.com/

 

The default configuration of WAP is to translate internal URLs to external URLs when you do pass-through authentication.   We had configured the org URL as ADFS pre-auth.  The discovery and auth URLs both used pass-through authentication.    The
external and internal names were the same and we used split DNS to handle internal versus external traffic.

The way CRM does authentication when using an internet facing deployment and ADFS is with the HTTP POST binding back to the auth URL.   The auth URL issues a DOMAIN cookie and redirects to the org URL.  In our case the domain cookie was scoped to *.crm.contoso.com.   The org web application gets the cookie and lets the user in. 

This breaks down with WAP because it attempts to remap the outbound cookie from the auth web application and reissue it under the external name (auth.crm.contoso.com).    When we redirect to the org URL it can’t see the cookie because the browser doesn’t pass it back.   The org URL then redirects back to ADFS, which redirects to auth, which reissues the cookie.   As you can see we’re stuck in an infinite redirect loop.   Eventually ADFS gets tried of this and fails issuing the following error in the log:

 

Microsoft.IdentityServer.Web.InvalidRequestException: MSIS7042: The same client browser session has made ‘6’ requests in the last ‘3’
seconds. Contact your administrator for details.

   at
Microsoft.IdentityServer.Web.Protocols.PassiveProtocolHandler.UpdateLoopDetectionCookie(WrappedHttpListenerContext
context)

   at
Microsoft.IdentityServer.Web.Protocols.WSFederation.WSFederationProtocolHandler.SendSignInResponse(WSFederationContext
context, MSISSignInResponse response)

   at
Microsoft.IdentityServer.Web.PassiveProtocolListener.ProcessProtocolRequest(ProtocolContext
protocolContext, PassiveProtocolHandler protocolHandler)

   at
Microsoft.IdentityServer.Web.PassiveProtocolListener.OnGetContext(WrappedHttpListenerContext
context)

 

The solution for this is to tell Web Application Proxy not to translate the outbound URLs in the response header.   This can be done via powershell and the Set-WebApplicationProxyApplication cmdlet.

 

http://technet.microsoft.com/en-us/library/dn283415.aspx

 



Set-WebApplicationProxyApplication -ID <id of auth web app> -DisableTranslateUrlInResponseHeaders

 

 

Now WAP will ignore the outbound cookie and let it pass along to the client as CRM had intended.   Presto!

Comments (18)

  1. Dan says:

    Just wondered have you managed to get the CRM Mobile app work externally via this method?

  2. vladimir says:

    So, you set all three published rules to "DisableTranslateUrlInResponseHeaders", correct?

    I can not make CRM mobile apps working (WP8, Nexus 7). WP8 app got IIS error on CRM server.

    Nexus 7 app show blank screen after ADFS login page and no error in servers log.

  3. Jason Vallery says:

    Hi Dan/Vladimir,

    To clarify –

    1) Set DisableTranslateUrlInResponseHeaders for all 3 published URLs

    2) Ensure you're not using ADFS pre-auth.   We ran into a problem with the Outlook connector not handling the 307 redirect correctly.   It worked fine when we disabled the pre-auth piece.

    I haven't tested the Android app but it worked great for iOS and Windows Phone.   Can you post back the error you're getting?

    -JV

  4. Vladimir says:

    As you mentioned, my org rule has adfs pre-auth. Dev and Auth – pass-through. Do I need to set all three rules to pass-through?

  5. Vladimir says:

    Here what i got on CRM server after trying WP8 CRM app:

    start app on phone, enter https://org.domain.com url, enter my domain credentials at adfs login page, got Ooops screen, tried once more, got 404 error after that error page "An error has ocured".

    Server event:

    Event code: 3005

    Event message: An unhandled exception has occurred.

    Event time: 1/20/2014 10:00:09 PM

    Event time (UTC): 1/20/2014 8:00:09 PM

    Event ID: c3195fd0250846d4838e108793cbb73e

    Event sequence: 3806

    Event occurrence: 20

    Event detail code: 0

    Application information:

       Application domain: /LM/W3SVC/1/ROOT-1-130346419733012091

       Trust level: Full

       Application Virtual Path: /

       Application Path: C:Program FilesMicrosoft Dynamics CRMCRMWeb

       Machine name: MY-CRM-SRV

    Process information:

       Process ID: 4640

       Process name: w3wp.exe

       Account name: DOMAINCRM_APPSRV

    Exception information:

       Exception type: InvalidOperationException

       Exception message: CRM Parameter Filter – Invalid parameter 'client_id=ms-app://s-1-15-2-2572088110-3042588940-2540752943-3284303419-1153817965-2476348055-1136196650/' in Request.QueryString on page /main.aspx

    The raw request was 'GET /main.aspx?client_id=ms-app://s-1-15-2-2572088110-3042588940-2540752943-3284303419-1153817965-2476348055-1136196650/' called from .

      at Microsoft.Crm.Application.ParameterFilter.ValidateParameter(HttpRequest request, ArrayList parameterCollection, String key, String value, ParameterSources source, EntityType pageEntityType, FormAdditionalAllowedParameters additionalAllowedParameters)

      at Microsoft.Crm.Application.ParameterFilter.ValidateParameters(Page page, EntityType pageEntityType, Boolean alwaysEnableParameterChecking, FormAdditionalAllowedParameters formAdditionalAllowedParametersTemp)

      at Microsoft.Crm.Application.ParameterFilter.ValidateParameters(Page page, EntityType pageEntityType, Boolean alwaysEnableParameterChecking)

      at Microsoft.Crm.Application.Controls.AppPage.ValidatePageParameters()

      at Microsoft.Crm.Application.Controls.AppPage.OnInit(EventArgs e)

      at System.Web.UI.Control.InitRecursive(Control namingContainer)

      at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

    Request information:

       Request URL: org.domain.com/main.aspx

       Request path: /main.aspx

       User host address: 1.1.1.2

       User: DOMAINuser

       Is authenticated: True

       Authentication Type: Federation

       Thread account name: DOMAINCRM_APPSRV

    ==== end was cutted========

  6. Jason Vallery says:

    Yes – we found that we had to set all 3 to pass-through for the clients to work.   The problem is that the client calls the Discovery.WSDL on the organization URL.   If pre-auth is enabled a 307 is returned which the client doesn't know how to handle.   If you disable pre-auth it should 302 redirect to ADFS instead which works.

  7. Vladimir says:

    3 publishing rules (pass-through) with Set DisableTranslateUrlInResponseHeaders – CHECK

    Win8 CRM Apps works – CHECK

    Android CRM App works – CHECK

    Thank you VERY VERY much!

  8. Dan says:

    I've got a lot futher now.

    But im getting the following on the ADFS server now

    Exception details:

    Microsoft.IdentityServer.RequestFailedException: MSIS9236: The OAuth authorization request contains invalid client or redirect URI. Failed to process the request. —> Microsoft.IdentityServer.Web.Protocols.OAuth.Exceptions.OAuthInvalidClientRedirectUriException: MSIS9224: Received invalid OAuth authorization request. The received 'redirect_uri' parameter is not a valid registered redirect URI for the client identifier: 'ce9f9f18-dd0c-473e-b9b2-47812435e20d'. Received redirect_uri: 'urn:ietf:wg:oauth:2.0:oob'.

      at Microsoft.IdentityServer.Web.Protocols.OAuth.OAuthAuthorization.OAuthAuthorizationRequestContext.Validate()

      at Microsoft.IdentityServer.Web.Protocols.OAuth.OAuthAuthorization.OAuthAuthorizationProtocolHandler.Process(ProtocolContext context)

      — End of inner exception stack trace —

      at Microsoft.IdentityServer.Web.Protocols.OAuth.OAuthAuthorization.OAuthAuthorizationProtocolHandler.HandleException(Exception ex, ProtocolContext context)

      at Microsoft.IdentityServer.Web.Protocols.OAuth.OAuthAuthorization.OAuthAuthorizationProtocolHandler.Process(ProtocolContext context)

      at Microsoft.IdentityServer.Web.PassiveProtocolListener.ProcessProtocolRequest(ProtocolContext protocolContext, PassiveProtocolHandler protocolHandler)

      at Microsoft.IdentityServer.Web.PassiveProtocolListener.OnGetContext(WrappedHttpListenerContext context)

    Microsoft.IdentityServer.Web.Protocols.OAuth.Exceptions.OAuthInvalidClientRedirectUriException: MSIS9224: Received invalid OAuth authorization request. The received 'redirect_uri' parameter is not a valid registered redirect URI for the client identifier: 'ce9f9f18-dd0c-473e-b9b2-47812435e20d'. Received redirect_uri: 'urn:ietf:wg:oauth:2.0:oob'.

      at Microsoft.IdentityServer.Web.Protocols.OAuth.OAuthAuthorization.OAuthAuthorizationRequestContext.Validate()

      at Microsoft.IdentityServer.Web.Protocols.OAuth.OAuthAuthorization.OAuthAuthorizationProtocolHandler.Process(ProtocolContext context)

  9. Jason Vallery says:

    Dan –   Can you email me a fiddler trace?   javaller@microsoft.com

    Thanks

  10. Dan says:

    Got it all working now Jason 🙂

    Forgot to add Oauth to ADFS Client ….doh

  11. Will S says:

    Hey Jason, I just setup new ADFS 2.2 box and when I try to log into CRM 2013 via mobile apps I just get prompted for login over and over. I havn't yet setup WAP but am on internal network (external does the same thing) and going directly to ADFS server. Internal CRM & external URL's do the same things. I have not gotten a 3rd party cert, but am instead using domain issued cert but I've installed the CA cert on the mobile devices. I also did a repair of the crm install after configuring claims & IFD, and registered the mobile apps on adfs server. The only thing I can think of is when I run:

    $fedurl = Get-CrmSetting -SettingType ClaimsSettings

    $fedurl.FederationProviderType = 1

    Set-CrmSetting $fedurl

    and then Get-CrmSetting -SettingType ClaimsSettings, the FederationProviderType stays 0 for some reason. Any ideas?

  12. luoyong says:

    I have the same problem, could anybody help?

    $fedurl = Get-CrmSetting -SettingType ClaimsSettings

    $fedurl.FederationProviderType = 1

    Set-CrmSetting $fedurl

    and then Get-CrmSetting -SettingType ClaimsSettings, the FederationProviderType stays 0 for some reason.

  13. Frank Carius says:

    Ok publishing CRM using WAP without preauth is not a big deal, Have you tried to use WAP with ADFS for Preauthentication and then using Kerberos contraint delegation to access the internal CRM page ?.  This looks much more interesting than using a simply anonymous reverse Proxy.

  14. Jamie says:

    I'm confused.  The title of your article is "Publishing CRM Internet Facing Deployment using Web Application Proxy", yet I can't any information in the article itself or any links that explain how to Publish CRM Internet Facing Deployment using Web Application Proxy.  Do you have another document somewhere that explains how to do this using a step-by-step method, or a link to a similar document?

  15. Jonathan Spigler says:

    I second Frank Carius post!

    Please see my post at

    social.technet.microsoft.com/…/publishing-crm-2011-on-web-applicaiton-proxy-using-kerberos-constrained-delegation

    Summary, i was able to get it working but i get that generic CRM error after logon.  Read my post for more info.

    bottom line it does work!  but only after you click the retry button and the page successfully loads.  you can do kcd though.  

  16. Stephen Daugherty says:

    Quick question, I  was able to get Claim Base Auth working internally, but I guess i'm failing to see the how a couple pieces of the puzzle fit together.

    I setup the rules in ADFS for IFD, and configured it to point to the AUTH address, which does pull up correctly.

    Next I'm must be over looking something here, how does the external addresses know to work together?

    ie how does the external CRM Org address, when using passthrough, know that it must use the IFD rule set to get back to the WAP?

  17. Rowan says:

    Has anyone managed to publish Dynamics CRM 4 (on windows 2008R2) with WAP running on a win2012 server (the old ISA 2006 host)?

    my scope is only to upgrade the windows OS for now and next year to upgrade the CRM version…. so as a replacment for the ISA I'm considering only upgrading the ISA server OS to 2012 and use the WAP to do the ISA's reverese proxy and AD authentication roles.

  18. Pragya says:

    Facing this error in ADFS server and redirection wot CRM dyanmics Dashboard is failed.

    Protocol Name:

    Saml

    Relying Party:

    Exception details:

    Microsoft.IdentityServer.Web.InvalidRequestException: MSIS7042: The same client browser session has made '6' requests in the last '11' seconds. Contact your administrator for details.

      at Microsoft.IdentityServer.Web.Protocols.PassiveProtocolHandler.UpdateLoopDetectionCookie(WrappedHttpListenerContext context)

      at Microsoft.IdentityServer.Web.Protocols.WSFederation.WSFederationProtocolHandler.SendSignInResponse(WSFederationContext context, MSISSignInResponse response)

      at Microsoft.IdentityServer.Web.PassiveProtocolListener.ProcessProtocolRequest(ProtocolContext protocolContext, PassiveProtocolHandler protocolHandler)

      at Microsoft.IdentityServer.Web.PassiveProtocolListener.OnGetContext(WrappedHttpListenerContext context)

    Any ideas how to solve it.

    Already tried

    Set-WebApplicationProxyApplication -ID <id of auth web app> -DisableTranslateUrlInResponseHeaders This doesnt seem to work,

    any other ideas??