One ADFS to serve them all! (Part I)
One ADFS to serve them all!
The goal is to use a vanity URL host name that your site is using and to also use that same host name to resolve ADFS, without having you redirected back to the ADFS original service name (hostname + URL). Because for the end users this shouldn't look like anything else but the vanity domain they are already connected to.
Thus how do we solve this? Follow this basic lab entry to get a feeling for the end solution. (I will post more about this subject in greater detail)
The ADFS Limitation.
The limitation I'm speaking of, in this case is the endpoint for SAML 2.0 / WS-Federation: "/adfs/ls"
(but as you can imagine it's pretty much every endpoint listed in ADFS)
We connect with the 1 possible value set during installation for the federation service name: "your.host.name"
Which results in all endpoints only being accessibly under that federation service name.
The solution.
And in walks ARR A.K.A Microsoft's application request and routing solution that runs on IIS 7.x and upwards. The version we will be using in our example is version 3.0 of ARR running on IIS 8.5 with Microsoft URL rewrite module version 2.0.
(This blogpost is based on ADFS with SharePoint. But with a little work you should be able to reuse this with different platform applications. An example might be a MVC application with WIF or Sitecore). The current post is without federation SSO support. But in my next blog i will post about getting it to work with SSO support.
Requirements.
- A Windows machine (I'm using Windows Server 2012 R2)
- A working understanding of SSL Certificates.
- A SharePoint environment (In this example I'm using SharePoint 2013)
- SSO is not working in this lab. (I will write a new blog post about having SSO with host name rewrite(s). Yes, that also works but is a little more complex)
The Goal.
I’m going to describe step by step how to get this working for a very basic scenario. SSO with federation won’t work in the scenario below. I also have this worked out and need to put it in a post. (Which will follow soon!)
The goal is to show you that it works and how easily it achieved. In later posts I will follow up and we will be getting in to more complex solution that will help in true business scenarios. (Truly using Regular expressions A.K.A. regex to make the rules more efficient and dynamic!)
I’ve vetted this solution with Microsoft and they currently acknowledge that it works and is commercially supported. I’ve asked them to put this forward to the product group to verify if it will be supported end to end. (For us enterprise IT guys this is really important!)
step1 "Configuring ADFS":
Just install your on premise ADFS server as you normally would.
Need help?
For ADFS 3.x checkout: Configure ADFS for Windows Server 2012 (R2)
For ADFS 2.0 checkout: Configuring Active Directory Federation Services
Step2 "Getting a SharePoint farm up and running":
Make sure you have your SharePoint environment up and running with your STS configured with the ADFS server you previously configured in step1 (If you hadn't one running yet)
For ADFS 2.0 check out Steve Peschka's excellent Blogpost for 2.0
And for ADFS 3.0 check out technet
Both references also have information in them for configuring ADFS in a default configuration.
Step3 "Installing ARR":
1. Open server manager and use the Add Roles and Features Wizard to add IIS, .Net 3.5 features including the Tracing Feature. (The Tracing feature is very important when troubleshooting ARR issues)
Figure B: Adding the features.
2a. Next, ensure that your certificate is installed on the server. I prefer to create a new website but you can also use the existing default website in IIS and just add a HTTPS binding. Make sure you're vanity host name is in the binding for 443!
Figure c: New IIS site.
You can use SNI to bind multiple host name on port 443 in IIS. But remember this will only work when the visiting browsers also support SNI.
3. Next where going to install the necessary IIS modules for this scenario using Microsoft "Web Platform Installer". You can trigger this from IIS itself or just hit the link to download i provider on the server itself.
Search for Application Request Routing in WebPI and select version 3.0 and hit Add. Hit install.
Figure D: WebPI search results box.
WebPI will tell you that it has a few other necessary prerequisites like:
Figure E: Prerequisites.
When everything is finished you should see something like the picture below.
Figure F: Results of WebPI.
In case you're not able to connect to the INTERNET from you're server you can always download the necessary modules manually from http://www.IIS.net. And install them the old school way ;)
Manual source links:
1. Open ARR from the top level within IIS.
Figure G: IIS top level panel.
2. Double click the "Application Request and Routing Cache" icon. And in the right side pane in the Action windows open up the link under Proxy "Server Proxy Settings"
In the center window mark Enable Proxy and set the HTTP Version to HTTP/1.1
Figure H: Application Request and Routing Proxy Settings.
TIP: Debug tricks you can use later on for troubleshooting / fine tuning!
(If you scroll down in the server proxy settings configuration you will see a part about add a proxy to forward the traffic through. A neat trick is to install fiddler2 on the ARR machine or somewhere else and put fiddler in that box to see what the ARR machine does.
Figure I: Using fiddler to debug traffic from ARR.
Step5 "Creating you're ARR reverse proxy":
1. Next we will create the necessary configuration on the website for the URL rewrite.
Remember in this case I'm trying give users the feeling they left original SharePoint 2013 site they opened. Normally you would be redirected in a passive federation scenario with a 307 to your ADFS with its one static host name (which is our WS-Federation endpoint in our case. See Figure A).
So I'm going to create a basic reverse proxy rule for this scenario.
Select your website in the left pane window in IIS manager and in the center pane select the URL Rewriting mod icon.
Figure J: Opening URL Rewrite module.
2. Next we will click on the Add rule link in the right window pane within IIS manager. This will open a new window which gives us a set of choices to make. In our case we will select "Reverse Proxy" and click OK.
Figure K: Adding URL Rewrite Rule(s).
3. Next we will type the host name of the server. In my case i used the same vanity host name inside my intranet configuration as is used for extranet users. This means i don't rewrite any host name(s) for my SharePoint Site-Collection. (I also don’t offload, so note that i unmarked “Enable SSL Offloading”)
(But it is supported as long as it’s just the host name you rewrite. But for this lab i wanted to keep it simple.)
Figure L: Reverse proxy configuration for SP site.
4a. Now where going to edit the just created rule we just created by double clicking on it. Or selecting the rule and clicking on “Edit…” in the pane on the right side beneath the inbound rules part of the pane.
We will append to the existing Pattern “^(https?)://” and type our vanity host name. In my lab being www.mysharepointsite.nl
The result of this will be that when an incoming connection enters ARR the rule will check if the host name part matches what we dat is filled in. If it matches the rule will be applied. If not it will ignore the rule.
Figure M: Editing the first rewrite rule Part I.
4b.Now we will correct the second part of the rule we opened in step 4. Please scroll down till you see the action window in the center pane. The current rewrite rule action in my case states that it will rewrite to:
“{C:1}://www.mysharepointsite.nl/{R:1}”
change this to,
https://www.mysharepointsite.nl/{R:1}
Why did I change {C:1} to https? Because in my scenario I only support https. Normally this part that we just replaced would be used to implement http or https bindings, based on conditions and other factors for the incoming connection instance.
Figure N: Editing the first rewrite rule Part II.
(If people are interested in more in depth posts on URL rewriting itself I could post something about this in a different blog post. Let me know, if it’s something you would be interested in as a reader! And what you’d specifically would want to know that isn’t out there yet or has very bad documentation)
5. Now where going to add another rule to the inbound rules list. This rule will catch the ADFS vanity (Endpoint) URL and rewrite the host name back to the original host name you're using for your ADFS endpoint service name. So again in the right side pane in IIS manager select "Add rule" and again add a reverse proxy rule. Yes, on the same IIS Site!
Figure O: adding another reverse proxy rule.
Figure P: setting up the reverse proxy rule.
Hit ok and let’s go ahead and also edit that rule by double clicking on it (ReverseProxyRule2). Or by using the link in the right side pane.
a.) First step will be editing the “Match URL” part. We will change the pattern from (.*) to “[a][d][f][s](.*)” . This will catch the redirect to ADFS and keep your current host name context for the connecting client, but on the other end behind ARR the connection context is being switched to your ADFS Service endpoint including the original ADFS hostname and URL. (yes, you can do this even smarter but for the regex beginners this a very simple way to grasp what we’re doing J )
Figure Q - Settings up Rule for ADFS II
b.) Let’s go on ahead and change the Condition as well. Let’s change the condition Input to {HTTPS}, Type to match the pattern and the pattern will ben “On”. (meaning is SSL used yes or no)
Figure R – Setting up the rule for ADFS III
c.)Now for the final part of the rule. Where going to change the Action again. The action
type will remain Rewrite. The Rewrite URL will be changed from:
{C:1}://login.myrealadfsendpointname.nl/{R:1}
To,
https://login.myrealadfsendpointname.nl/{R:0}.
Again I’m trying to keep it as simple as possible for the lab experiment. There’s a nicer method then the one I’m showing you now. But the result is what counts. Plus you now have basic understanding of what it could do for you!
6. Now that we've finished changing the Rule. Let’s hit Apply and go back to rules section. The final step is to change the order of the rules! This is very important, the rules are processed according to order. So from top to bottom the rules are parsed.
When a URL request come's along we need Inboundrule2 to catch it so we have to move it to the top of the list. Because we told with the rule inboundrule2 to check for “/ADFS/” in the first part of the URL it will apply its action to it and rewrite the host name before the URL for the client on the ARR Server (without the client actually noticing it) to:
When a URL request come's along we need Inboundrule2 to catch it so we have to move it to the top of the list. Because we told with the rule inboundrule2 to check for “/ADFS/” in the first part of the URL it will apply its action to it and rewrite the host name before the URL for the client on the ARR Server (without the client actually noticing it) to:
https://www.mysharepointsite.nl/adfs/ls?wa=wsignin1.0&wtrealm=https%3a%2f%www.mysharepointsite.nl&wctx=https%3a%2f%www.mysharepointsite.n%2f_layouts%2f15%2fAuthenticate.aspx%3fSource%3d%252F&wreply=https%3a%2f%www.mysharepointsite.n%2f_trust%2fdefault.aspx
Figure S: Switching rule order.
Voila, now it looks all activitity is happening on www.mysharepointsite.nl while behind the scene's were actually using two different servers with different hostnames.
Conclusion.
So if al when't well you should have a working URL rewrite which hides your ADFS connection behind your SharePoint web application URL. The user thinks al traffic is to one server when actually its being managed by ARR to connect to your ADFS server and SharePoint server under the URL that is used for your webapplication in SharePoint namely: www.mysharepointsite.nl. I'd like to thank my colleague B. Danse for his help in verifying the solution and helping me out in the beginning with my limited understanding of regular expressions at the time.
Reacties
Een reactie posten