Publishing a SAML app through the Azure AD Application Proxy
Updated: Feb 26, 2018
I was intrigued the other day when a question was posted to a private distribution list that I belong to. The question was asking about publishing an application, that used SAML authentication, through the Azure AD Application Proxy. In the question, it was pointed out that there was no way to choose SAML as the authentication protocol to the internal application, further a screenshot of an error message was included that stated “Application Proxy cannot be configured for an application that uses SAML Single Sign-on configuration. Please disable SAML in order to use Application Proxy for this application.”
The error message is shown in Figure 1, really peaked my interest. I have worked with the Azure AD Application Proxy for years and wrote a troubleshooting whitepaper for Microsoft in 2015, you can find it here . During all this time I have never seen this error message, it also amused me that the error message referred to the Application Proxy. When I was writing the whitepaper and subsequently presenting sessions at Microsoft Ignite, I was told never to refer to the proxy other than by its full name, the Azure AD Application Proxy.
I finally managed to reproduce the error message and realised that the configuration in the portal is confusing and probably worth discussing in a short blog, so here it is.
To publish an application that uses a federated authentication protocol through the Azure AD Application Proxy is a two-stage process. Firstly, you need to register the application in Azure AD and test that that is working correctly on the internal network. The simplest way to register a SAML application is via the Enterprise application blade, select New application and then Non-gallery application. You will see that you can register an application that can use SAML-based SSO or Password-based SSO, additionally you can use SCIM to automatically provision users to the application. If you want to register a WS-Federation or OpenID Connect / OAuth 2.0 applications, this should be done through the App registrations blade.
Once the application is working correctly, it can be published through the Azure AD Application Proxy. And here is where things had gone wrong. If you look via the Enterprise applications blade at the configuration for the SAML app, it shows an Application Proxy option. Figure 2, the name of the application is SAML-TK.
Don’t touch this option, this is not where you configure the Azure AD Application Proxy to publish the application. If you attempt to configure it here, you will get an error message as shown in Figure 1. As with the UX in the App registrations blade, the configuration has to manage different application types, and some options will be available even if you are configuring an application to which the option doesn’t apply. It’s not nice, but that’s the way it is.
I hear you asking, “How do we create the proxy?”. To create a proxy for our SAML application you need to create a new enterprise application, choose the option to create an On-premises application. Here you set the internal URL of your SAML app and choose if you want to use pre-authentication. If the pre-authentication is set to Azure Active Directory, the user is required to authenticate to Azure AD before any traffic is allowed through the proxy to the internal application.
The important thing to realise is that for a federated app published through the Azure AD application Proxy the authentication to the app is completely independent of the pre-authentication to the proxy. For the proxy, you need to set the SSO mode (Figure 3) to Azure AD single sign-on disabled.
The Azure AD Application Proxy and the app are registered independently. See Figure 4.
Take a look at Figure 5, below is a simplified explanation of the steps involved in accessing the App. All the interactions involve the user’s browser.
1. The browser accesses the app via the external URL.
2. The proxy realises the user is not authenticated and triggers an OpenID Connect authentication request to Azure AD.
3. The user authenticates to Azure AD and gets an id_token and an SSO cookie.
4. The browser POSTs the id_token to the proxy.
5. The proxy validates the id_token and sets an edge access cookie and redirects the browser back to the application via the external URL.
6. The edge access cookie allows the GET request to pass to the internal application.
7. The internal application realises the user is not authenticated and triggers a SAML authentication request to Azure AD
8. The SAML authentication request is passed to Azure AD along with the SSO cookie received in step 3.
9. The SSO cookie proves the user’s authentication to Azure AD and a SAML response is created.
10. The browser posts the SAML response to the app via the proxy.
11. The app validates the SAML token in the response and issues an app authentication cookie.
12. All further requests pass through the proxy using the edge access cookie, and the user remains authenticated to the app via the app authentication cookie.
From these steps, you can see that the Proxy and SAML app are acting independently, from an authentication perspective, and both must be registered in Azure AD as separate entities, Figure 4.
Figure 6 is proof that it all works!
One last gotcha, the SAML application will set the reply URL in the SAML authentication request. This is the URL that the SAML token should be returned to after the user is authentication by Azure AD, in SAML speak this URL is called the AssertionConsumerServiceURL. For security reasons, Azure AD will only trigger a return to this URL if a matching URL is configured in Azure AD as part of the application registration (application registration not the proxy registration). The SAML request containing the AssertionConsumerServiceURL is XML which has been deflated and encoded, consequently the proxy cannot rewrite the value to point to the proxy’s external URL. This results in you either configuring the return URL to the internal app ACS URL or the external app ACS URL and choosing if the app works internally or externally. In my example Figure 6, I set the ACS URL in the app to the external proxy URL and configured the reply URL in Azure AD to match. The best practice solution is to use the same internal and external URLs.
I hope this blog post helps, good luck publishing you SAML apps through the Azure AD Application Proxy. If you enjoyed the blog, please let me know on Twitter @john_craddock.