Leveraging Azure AD authentication for an on-premise web app

I’ve been experimenting with using Azure AD for authentication of an on-premise web app. I thought I’d share some of my findings so far.

 

I was writing a web app to provide reporting on simple bind data UWWI is now collecting. When I added a asp.net web project to my Visual Studio solution, it asked me what authentication I wanted to use, with 3 or 4 choices. Since it happened to be a leap forward day, I decided to give AAD a try (to be clear, I’ve been intending to try this out for about 9 months, but never found the time).

 

The on-boarding process was amazingly simple. I happen to have a global admin account in our AAD, and currently without that, the experience isn’t as simple, but my understanding is that level of privilege won’t always be necessary in the future. In other words, in order to create the application in AAD, you currently need to be an AAD global admin. When I compare the on-board process of what it takes for a web app to integrate to an equivalent federated authentication solution that uses UW NetIDs, like Shibboleth or ADFS, there’s really no comparison. I had a registered app with working authentication within 30 seconds—and all from within Visual Studio.

 

Now, if I had a more complicated use case, e.g. I was writing a web service that other web apps could interact with, then the initial configuration to get multiple party OAuth setup would have been beyond that, but today there is no UW OAuth offering (or if there is, it isn’t documented). I haven’t experimented here, but I think Eric might have been looking into this.

 

My next (and active) hurdle was realizing that my AAD credentials wouldn’t allow me to get access to the SQL server where the data my report needed to access was. There are two solutions I can take to solve this. A common solution many websites take is to use the web app pool’s credentials to get access to the data. I’m generally not a fan of that type of architecture, because it complicates the audit picture and there is a strong temptation to not actually write the auditing the web app must now must do, so I resisted that. I spoke with a colleague of mine, Brian Desmond, and he suggested I leverage KCD (Kerberos constrained delegation) to transition the AAD credential to an AD credential—he had done this exact thing several times for similar use cases. Turns out that the C2WTS service (Claims to Windows Token Service) that was released with ADFS 1 was subsequently more broadly released with WIF 3.5. This service is commonly used with Sharepoint 2010 when it is configured to use federated authentication, e.g. see http://support.microsoft.com/kb/2722087. So I now need to explore writing some code that leverages the C2WTS stuff, which fortunately there are nice code examples for at http://msdn.microsoft.com/en-us/library/ee517278.aspx.

 

I’m beginning to think there is a nice emerging and reproducible authentication integration pattern here for future .NET web apps. You end up with a web app that has federated authentication, can benefit from all the cool AAD capabilities Microsoft is pouring investment into (like RBAC), but you can still get all the benefits of the traditional AD logon token. There’s a lot more to explore here before labeling it a preferred integration pattern, but it has definite potential in my mind.

 

Obviously I haven’t finished (and given my spare time to work on things like this, I probably won’t for a while), but I did think this was worth sharing more broadly.

 

If others have a web app they’d like to provision to Azure AD, let one of the AAD global admins know, and we’ll get your web app provisioned.

 

Azure AD RBAC

The URL in the tweet below talks about using a feature I’ve been talking about here at the UW—the emerging Azure AD RBAC capabilities.

 

The blog post below talks about using this feature in the context of a web app hosted in an Azure Website, but the capability is designed to be used by a web app hosted anywhere.

 

The post only talks about the 3 built-in roles, but the capability is designed so you can define your own custom roles—they just haven’t released that option yet.

 

If folks are interested in reading up on this, here are some good starting points:

 

Background: http://azure.microsoft.com/en-us/documentation/articles/role-based-access-control-configure/

 

Developers: http://social.technet.microsoft.com/wiki/contents/articles/4075.role-based-access-control-rbac-authorization-in-claims-aware-applications-and-services.aspx

 

Example app walkthrough: http://msdn.microsoft.com/en-us/library/azure/dn385717.aspx

 

David Ebbo (@davidebbo)
1/5/15 2:25 PMGreat article on the use of Role Based Access Control (RBAC) in Azure Websites: azure.microsoft.com/blog/2015/01/0… #azure #websites #rbac

DCs, time event 142, w32time, and group policy

Over a year ago, we applied a fix related to this on our domain controllers because of intermittently reported client problems. This fix was the most significant finding out of Microsoft AD RAP as a service engagement that we had.

Turns out that down in the deep details of the time settings there’s a lot that can cause problems. And Microsoft deployed poor values for many of those settings for prior OSes, some of which got encoded in the default group policy values. We turned on those group policy settings back when the values were really bad, and of course, those bad values were still in place because nothing will automatically change an existing GPO setting.

 

Here’s a table summarizing the craziness:

  2008R2 Admx Defaults 2008 / 2008R2 DC Default* 2008 / 2008R2 Member Defaults 2003 Adm Defaults 2003 DC Defaults
FrequencyCorrectRate 4 4 4 4 4
HoldPeriod 5 5 5 5 5
LargePhaseOffset 50000000 50000000 50000000 128000 50000000
MaxAllowedPhaseOffset 300 300 300 300 300
MaxNegPhaseCorrection 172800 172800 4294967295 54000 4294967295
MaxPosPhaseCorrection 172800 172800 4294967295 54000 4294967295
PhaseCorrectRate 1 7 1 1 7
PollAdjustFactor 5 5 5 5 5
SpikeWatchPeriod 900 900 900 90 900
UpdateInterval 100 100 30000 30000 100
AnnounceFlags 10 10 10 10 10
EventLogFlags 2 2 2 2 3
LocalClockDispersion 10 10 10 10 10
MaxPollInterval 10 10 15 15 6
MinPollInterval 6 6 10 10 10

* These are the settings you want on you DCs as they are the OS defaults for a DC

 

On your DCs, you want to apply what’s in the column labeled “2008/2008R2 DC Default*”. To correct our problem, I turned off all the GPO time settings. Then I turned them back on. Then I fixed the only setting whose (GPO) default value doesn’t match the OS default value for a DC (PhaseCorrectRate).

 

This fixed all of the time events being raised in our domain.

 

YMMV, but I expect this will likely help quite a few folks.

Windows Firewall + PowerShell + Group Policy = Wonderful

Last year I did some work around putting together a group policy for the UWWI servers that restricts who can access them to the current definition of the UW Network.

Group policy allows you to define configuration settings once and apply them broadly. And what better application than the Windows Firewall rules that are so crazily detailed and finicky? Who likes to set local Windows Firewall rules? Yuck.

James Morris tipped me off that there were some PowerShell cmdlets that would help me. And he was absolutely right … there was one which really saved a massive amount of time in defining the rules that went in the GPO.

Here are some breadcrumbs that should allow you to put something similar together yourself.

The UW-IT NOC has this document defining the UW Networks: https://wiki.cac.washington.edu/display/UWNOC/IP+Address+Space+Usage

Note that includes both IPv4 and IPv6. And Windows Firewall handles both. 🙂

So then you do something like this:

PS C:\Windows\system32> $IPs = @(“128.208.0.0/16″,”128.95.0.0/16″,”140.142.0.0/16″,”198.48.64.0/19″,”205.175.96.0/19″,”69.91.128.0/17″,”173.250.128.0/17″,”108.179.128.0/18″,”172.16.0.0/12″,”10.0.0.0/8″,”2607:4000::/32″,”fd73:a9bd:11bb::/48”)

Then you create your group policy object. Let’s say I created mine in the Dogfood domain, with a name of “uwit: UWWI firewall test”.

You then do something like this:

PS C:\Windows\system32> set-netfirewallrule -DisplayName “Windows Remote Management – Compatibility Mode (HTTP-In)” -RemoteAddress $IPs -PolicyStore “dogfood.netid.washington.edu\uwit: uwwi firewall test”

This adds a firewall rule to the GPO for WinRm that restricts traffic to the IP networks in the $IPs variable.

If you pull up the GPO in the GUI, you’ll now see that firewall rule in the GPO. Nice! 🙂

The next trick is figuring out which rules you need to add, and that really depends on the box and how tight you want to configure it. On thing to consider: you might go with a course grain approach, restricting TCP & UDP & ICMP traffic, and skip the fine grain approach of delineating all the individual services.

Want to read up on the Windows Firewall with Advanced Security? See http://technet.microsoft.com/en-us/library/cc754274.aspx. If you do dig into it and go the more fine grain route, make sure you understand the Windows Service Hardening type of firewall rules. These are rules defined by the product team (or 3rd party apps/services) and can’t be removed easily. In other words, they are on every box that has the Windows Firewall service installed, and **regardless of whether you have the Windows Firewall on or off**, they exist and are active. And yes, you read that right–there are firewall rules which are active even with Windows Firewall disabled. These
Windows Service Hardening rules are designed to only allow the services to accept traffic from the network sources the service is designed for.