Home / My Disclaimer / Who am I? / Search... / Sign in

// ADFS

Windows Azure Pack Authentication Part 3.5 – Using ADFS

by Steve Syfuhs / February 26, 2014 06:00 PM

Since we looked at using a custom IdP for Windows Azure Pack last time I figured it would be good to explicitly list some resources for those looking to use ADFS instead as that’s a fairly common scenario people are exploring.

Building Clouds

  1. Federated Identities to Windows Azure Pack through AD FS – Part 1 of 3: http://blogs.technet.com/b/privatecloud/archive/2013/12/17/federated-identities-to-windows-azure-pack-through-ad-fs-part-1-of-3.aspx
  2. Federated Identities to Windows Azure Pack through AD FS – Part 2 of 3: http://blogs.technet.com/b/privatecloud/archive/2013/12/17/federated-identities-to-windows-azure-pack-through-ad-fs-part-2-of-3.aspx
  3. Federated Identities to Windows Azure Pack through AD FS – Part 3 of 3: http://blogs.technet.com/b/privatecloud/archive/2013/12/18/federated-identities-to-windows-azure-pack-through-ad-fs-part-3-of-3.aspx

TechNet

Configure Active Directory Federation Services for Windows Azure Pack: http://technet.microsoft.com/en-us/library/dn296436.aspx

Windows Azure Pack (#WAPack) and Related Blogs, Videos and TechNet Articles: http://social.technet.microsoft.com/wiki/contents/articles/20689.windows-azure-pack-wapack-and-related-blogs-videos-and-technet-articles.aspx

Hyper-V.nu

  1. Windows Azure Pack with ADFS and Windows Azure Multi-Factor Authentication – Part 1: http://www.hyper-v.nu/archives/mvaneijk/2014/01/windows-azure-pack-with-adfs-and-windows-azure-multi-factor-authentication-part-1/
  2. Windows Azure Pack with ADFS and Windows Azure Multi-Factor Authentication – Part 2: http://www.hyper-v.nu/archives/mvaneijk/2014/02/windows-azure-pack-with-adfs-and-windows-azure-multi-factor-authentication-part-2/

As more people start diving into production deployments of Windows Azure Pack I suspect we’ll see more articles around using ADFS too. For an up to date curated list of content for Windows Azure Pack take a look at the TechNet Wiki above.

Windows Azure Pack Authentication Part 3 – Using a Third Party IdP

by Steve Syfuhs / February 07, 2014 06:22 PM

In the previous installments of this series we looked at how Windows Azure Pack authenticates users and how it’s configured out of the box for federation. This time around we’re going to look at how you can configure federation with a third party IdP.

Microsoft designed Windows Azure Pack the right way. It supports federation with industry protocols out of the box. You can’t say that for many services, and you certainly can’t say that those services support it natively for all versions – more often than not you have to pay extra for it.

Windows Azure Pack supports federation, and actually uses it to authenticate users by default. This little fact makes it easy to federate to a 3rd party IdP.

If we searched around we will find lots of resources on federating to ADFS, as that’s Microsoft’s federation product, and there are a number of good (German content) walkthroughs on how you can get it working. If you want to use ADFS go read one or all of those articles as everything we talk about today will be about using a non-Microsoft federation service.

Before we begin though I’d like to point out that Microsoft does have some resources on using 3rd party IdPs, but unfortunately the information is a bit thin in some places.

Prerequisites

Federation is a complex beast and we should be clear about what is required to get it working. In no particular order you need the following:

  • STS that supports the WS-Federation (passive) protocol
  • STS that supports WS-Federation wrapped JSON Web Tokens (JWT)
  • Optional: STS that supports WS-Trust + JWT

If you plan to use the public APIs with federated accounts then you will need a STS that supports WS-Trust + JWT.

If you don’t have a STS that can support these requirements then you should really consider taking a look at ADFS, or if you’re looking for customization, Thinktecture Identity Server. Both are top notch IdPs (edit: insert pitch about the IdP my company builds and sells as well [edit-edit: our next version natively supports JWT] Winking smile -- sorry, this concludes the not-so-regularly-scheduled product placement).

Another option is to roll your own IdP. Don’t do this. No seriously, don’t. It’s a complicated mess. You’re way better off using the Thinktecture server and extending it to fit your needs.

Supposing though that you already have an IdP and want to support JWT though, here’s how we can do it. In this context the IdP is the overarching identity providing system and the STS is simply the service issuing tokens.

Skip this next section if you just want to see how to configure Windows Azure Pack. That’s the main part that’s lacking in the MSDN documentation.

JWT via IdentityModel

First off, you need to be using .NET 4.5, and you need to be using the the 4.5 IdentityModel stack. You can’t use the original 3.5 bits.

At this point I’m going to assume you’ve got a working IdP already. There are lots of articles out there explaining how to build one. We’re just going to mod the STS.

Before making any code changes though you need to add the JWT token handler, which is easily installed via Nuget (I Red heart Nuget):

PM> Install-Package System.IdentityModel.Tokens.Jwt

This will need to be added to the project that exposes your STS configuration class.

Next, we need to inject the token handler into the STS pipeline. This can easily be done by adding an entry to the web.config system.identityModel section:

Or if you want to hardcode it you can add it to your SecurityTokenServiceConfiguration class.

There are of course other (potentially better) ways you can add it in, but this serves our purpose for the sake of a sample.

By adding the JWT token handler into the STS pipeline we can begin issuing JWTs to any relying parties that request one. This poses a problem though because passive requests don’t have a requested token type tacked on. Active (WS-Trust) requests do, but not passive. So we need to specify that a JWT should be minted instead of a SAML token. This can be done in the GetScope method of the STS class.

All we really needed to do was specify the TokenType as WIF will use that to determine which token handler should be used to mint the token. We know this is the value to use because it’s exposed by the GetTokenTypeIdentifiers() method in the JWTSecurityTokenHandler class.

Did I mention the JWT library is open source?

So now at this point if we made a request for token to the STS we could receive a WS-Federation wrapped JWT.

If the idea of using a JWT instead of a SAML token appeals to you, you can configure your app to use the JWT token handler similar to Dominick’s sample.

If you were submitting a WS-Trust RST to the STS you could use client code along the lines of:

When the GetScope method is called the request.TokenType should be set to whatever you passed in at the client. For more information on service calls you can take a look at the whitepaper Claims-Based Identity in Windows Azure Pack (docx). A future installment of this series might have more information about using services.

Lastly, we need to sign the JWT. The only caveat to using the JWT token handler is that the minimum RSA key size is 2048 bits. If you’re using a key smaller than that then please upgrade it. We’re going to overlook the fact that the MSDN article shows how to bypass minimum key sizes. Seriously. Don’t do it. I don’t want to have to explain why (putting paranoia aside for a moment, 1024 is being deprecated by Windows and related services in the near future anyway).

Issuing Tokens to Windows Azure Pack

So now we’re at a point where we can mint a JWT token. The question we need to ask now is what claims should this token contain? Looking at Part 1 we see that the Admin Portal requires UPN and Group claims. The tenant portal only requires the UPN claim.

Lucky for us the JWT token handler is smart. It knows to transform certain known XML-token-friendly-claim-types to JWT friendly claim types. In our case we can use http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn in our ClaimsIdentity to map to the UPN claim, and http://schemas.xmlsoap.org/claims/Group to map to our Group claim.

Then we need to determine where to send the token, and who to address it to. Both the tenant and admin sites have Federation Metadata documents that specify this information for us. If you’ve got an IdP that can parse the metadata then all you need to do is point it to https://yourtenantsite/FederationMetadata/2007-06/FederationMetadata.xml for the tenant configuration or https://youradminsite/FederationMetadata/2007-06/FederationMetadata.xml for the admin configuration.

Of course, this information will also map up to the configuration elements we looked at in Part 2. That’ll tell us the Audience URI and the Reply To for both sites.

Finally we have everything we need to mint the token, address it, and send it on its way.

Configuring Windows Azure Pack to Trust your Token

The tokens been sent and once it hits either the tenant or admin site it’ll promptly be ignored and you’ll get an ugly error message saying “nope, not gonna happen, bub.”

We therefore need to configure Windows Azure Pack to trust our token. Looking at MSDN we see some somewhat useful information telling us what we need to modify, but frankly, its missing a bunch of information so we’re going to ignore it.

First things first: if your IdP publishes a Federation Metadata document then you can just configure everything via PowerShell:

You can replace the target “Admin” with “Tenant” if you want to configure the Tenant Portal. The only caveat with doing it this way is that the metadata document needs to be accessible from the server. I’ve submitted a feature request that they also support local file paths too; hopefully they listen! Since the parameter takes the full URL you can put the metadata document somewhere public if its not normally accessible. You will only need the metadata accessible while applying this configuration.

If the cmdlet completed successfully then you should be able to log in from your own IdP. That’s all there is to it for you. I would recommend seriously considering going this route instead of configuring things manually.

Otherwise, lets carry on.

Since we can’t import our federation metadata (since we probably don’t have any), we need to configure things manually. To do that we need to modify settings in the database.

Looking back to Part 2 we see all the configuration elements that enable our federated trust to the default IdPs. We’ll need to update a few settings across the Microsoft.MgmtSvc.Store and Microsoft.MgmtSvc.PortalConfigStore databases.

As per the MSDN documentation it says to modify the settings in the PortalConfigStore database. It’s wrong. It’s incomplete as that’s only part of the process.

The PortalConfigStore database contains the settings used by the Tenant and Admin Portals to validate and request tokens. We need to modify these settings to use our custom IdP. To do so locate the Authentication.IdentityProvider setting in the [Config].[Settings] table.  The namespace we need to choose is dependent on which site we want to configure. In our case we select the Admin namespace. As we saw last time it looks something like:

We need to substitute our STS information here. The Realm is whatever your STS issuer is, and the Endpoint is where ever your WS-Federation endpoint is located. The Certificate should be a base 64 encoded representation of your signing certificate (remember, just the public key).

In my experience I’ve had to do an IISRESET on the portals to get the settings refreshed. I might just be impatient though.

Once those values are replaced you can try logging in. You should be redirected to your IdP and if you issue the token properly it’ll hit the portal and you should be logged in. Unfortunately this’ll actually fail with a non-useful error message.

deadsession

Who can guess why? So far I’ve stated that the MSDN documentation is missing information. What have we missed? Hopefully if you’ve read the first two parts of this series you’re yelling at the screen telling me to get on with it already because you’ve caught on to what I’m saying.

We haven’t configured the API services to trust our STS! Oops.

With that being said, we now have proof that Windows Azure Pack flows the token to the services from the Portal and, more importantly, the services validate the token. Cool!

Anyway, now to configure the APIs. Warning: complicated.

In the Microsoft.MgmtSvc.Store database locate the Settings table and then locate the Authentication.IdentityProvider.Secondary element in the AdminAPI namespace. We need to update it with the exact same values as we put in to the configuration element in the other database.

If you’re only wanting to configure the Tenant Portal you’d want to modify the Authentication.IdentityProvider.Primary configuration element. Be careful with the Primary/Secondary elements as they can get confusing.

If you’re configuring the Admin Portal you’ll need to update the Authentication.IdentityProvider.Secondary configuration element in the TenantAPI namespace to use the configuration you specified for the Admin Portal as well. As I said previously, I think this is because the Admin Portal calls into the Tenant API. The Admin Portal will use an admin-trusted token – therefore the TenantAPI needs to trust the admin’s STS.

Now that you’ve completed configuration you can do an IISRESET and try logging in. If you configured everything properly you should now be able to log in from your own IdP.

Troubleshooting

For those rock star Ops people who understand identity this guide was likely pretty easy to follow, understand, and implement. For everyone else though, this was probably a pain in the neck. Here are some troubleshooting tips.

Review the Event Logs
It’s surprising how many people forget that a lot of applications will write errors to the Windows Event Log. Windows Azure Pack has quite a number of logs that you can review for more information. If you’re trying to track down an issue in the portals look in the MgmtSvc-*Site where * is Tenant or Admin. Errors will get logged there. If you’re stuck mucking about the APIs look in the MgmtSvc-*API where * is Tenant, Admin, or TenantPublic.

Enable Development Mode
You can enable developer mode in sites by modifying a value in the web.config. Unprotect the web.config by calling:

And then locate the appSetting named Microsoft.Azure.Portal.Configuration.PortalConfiguration.DevelopmentMode and set the value to true. Be sure to undo and re-protect the configuration when you’re done. You should then get a neat error tracing window show up in the portals, and more diagnostic information will be logged to the event logs. Probably not wise to do this in a production environment.

Use the PowerShell CmdLets
There are a quite a number of PowerShell cmdlets available for you to learn about the configuration of Windows Azure Pack. If you open the Windows Azure Pack Administration PowerShell console you can see that there are two modules that get loaded that are full of cmdlets:

PS C:\Windows\system32> get-command -Module MgmtSvcConfig

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Cmdlet          Add-MgmtSvcAdminUser                               MgmtSvcConfig
Cmdlet          Add-MgmtSvcDatabaseUser                            MgmtSvcConfig
Cmdlet          Add-MgmtSvcResourceProviderConfiguration           MgmtSvcConfig
Cmdlet          Get-MgmtSvcAdminUser                               MgmtSvcConfig
Cmdlet          Get-MgmtSvcDatabaseSetting                         MgmtSvcConfig
Cmdlet          Get-MgmtSvcDefaultDatabaseName                     MgmtSvcConfig
Cmdlet          Get-MgmtSvcEndpoint                                MgmtSvcConfig
Cmdlet          Get-MgmtSvcFeature                                 MgmtSvcConfig
Cmdlet          Get-MgmtSvcFqdn                                    MgmtSvcConfig
Cmdlet          Get-MgmtSvcNamespace                               MgmtSvcConfig
Cmdlet          Get-MgmtSvcNotificationSubscriber                  MgmtSvcConfig
Cmdlet          Get-MgmtSvcResourceProviderConfiguration           MgmtSvcConfig
Cmdlet          Get-MgmtSvcSchema                                  MgmtSvcConfig
Cmdlet          Get-MgmtSvcSetting                                 MgmtSvcConfig
Cmdlet          Initialize-MgmtSvcFeature                          MgmtSvcConfig
Cmdlet          Initialize-MgmtSvcProduct                          MgmtSvcConfig
Cmdlet          Install-MgmtSvcDatabase                            MgmtSvcConfig
Cmdlet          New-MgmtSvcMachineKey                              MgmtSvcConfig
Cmdlet          New-MgmtSvcPassword                                MgmtSvcConfig
Cmdlet          New-MgmtSvcResourceProviderConfiguration           MgmtSvcConfig
Cmdlet          New-MgmtSvcSelfSignedCertificate                   MgmtSvcConfig
Cmdlet          Protect-MgmtSvcConfiguration                       MgmtSvcConfig
Cmdlet          Remove-MgmtSvcAdminUser                            MgmtSvcConfig
Cmdlet          Remove-MgmtSvcDatabaseUser                         MgmtSvcConfig
Cmdlet          Remove-MgmtSvcNotificationSubscriber               MgmtSvcConfig
Cmdlet          Remove-MgmtSvcResourceProviderConfiguration        MgmtSvcConfig
Cmdlet          Reset-MgmtSvcPassphrase                            MgmtSvcConfig
Cmdlet          Set-MgmtSvcCeip                                    MgmtSvcConfig
Cmdlet          Set-MgmtSvcDatabaseSetting                         MgmtSvcConfig
Cmdlet          Set-MgmtSvcDatabaseUser                            MgmtSvcConfig
Cmdlet          Set-MgmtSvcFqdn                                    MgmtSvcConfig
Cmdlet          Set-MgmtSvcIdentityProviderSettings                MgmtSvcConfig
Cmdlet          Set-MgmtSvcNotificationSubscriber                  MgmtSvcConfig
Cmdlet          Set-MgmtSvcPassphrase                              MgmtSvcConfig
Cmdlet          Set-MgmtSvcRelyingPartySettings                    MgmtSvcConfig
Cmdlet          Set-MgmtSvcSetting                                 MgmtSvcConfig
Cmdlet          Test-MgmtSvcDatabase                               MgmtSvcConfig
Cmdlet          Test-MgmtSvcPassphrase                             MgmtSvcConfig
Cmdlet          Test-MgmtSvcProtectedConfiguration                 MgmtSvcConfig
Cmdlet          Uninstall-MgmtSvcDatabase                          MgmtSvcConfig
Cmdlet          Unprotect-MgmtSvcConfiguration                     MgmtSvcConfig
Cmdlet          Update-MgmtSvcV1Data                               MgmtSvcConfig

As well as the MgmtSvcConfig module which is moreso for daily administration.

Read the Windows Azure Pack Claims Whitepaper
See here: Claims-Based Identity in Windows Azure Pack (docx).

Visit the Forums
When in doubt take a look at the forums and ask a question if you’re stuck.

Email Me
Lastly, you can contact me (steve@syfuhs.net) with any questions. I may not have answers but I might be able to find someone who can help.

Conclusion

In the first two parts of this series we looked at how authentication works, how it’s configured, and now in this installment we looked at how we can configure a third party IdP to log in to Windows Azure Pack. If you’re trying to configure Windows Azure Pack to use a custom IdP I imagine this part is the most complicated to figure out and hopefully it was documented well enough. I personally spent a fair amount of time fiddling with settings and most of the information I’ve gathered for this series has been the result of lots of trial and error. With any luck this series has proven useful to you and you have more luck with the configuration than I originally did.

Next time we’ll take a look at how we can consume the public APIs using a third party IdP for authentication.

In the future we might take a look at how we can authenticate requests to a service called from a Windows Azure Pack add-on, and how we can call into Windows Azure Pack APIs from an add-on.

Windows Azure Active Directory Federation In Depth (Part 2)

by Steve Syfuhs / December 07, 2012 10:02 PM

In my last post I talked a little bit about the provisioning and federation processes for Office 365 and Windows Azure Active Directory (WAAD). This time around I want to talk a little bit about how the various pieces fit together when federating an on premise Active Directory environment with WAAD and Office 365. You can find lots of articles online that talk about how to configure everything, but I wanted to dig a little deeper and show you why everything is configured the way it is.

Out of the box a Windows Azure Active Directory tenant manages users for you. You can create all your users online without ever having to configure anything on premise. This works fairly well for small businesses and organizations that are wanting to stop managing identities on premise altogether. However, for more advanced scenarios organizations will want to synchronize their on-premise Active Directory with WAAD. Getting this working revolves around two things: the users, and the domain.

First off, lets take a quick look at the domain. I’m using the Microsoft Online Services Module for PowerShell to query for this information. I’m going to use my domain as an example: syfuhs.net.

PS C:\Users\Steve\Desktop> Get-MsolDomain -DomainName syfuhs.net | fl *

Authentication : Managed
Capabilities   : Email, OfficeCommunicationsOnline
IsDefault      : True
IsInitial      : False
Name           : syfuhs.net
RootDomain     :
Status         : Verified

The important thing to look at is the Authentication attribute. It shows Managed because I haven’t configured federation for this domain.

If we then take a look at a user we see some basic directory information that we entered when the user was created. I’ve removed a bit of the empty fields but left an important one, the ImmutableId field.

PS C:\Users\Steve\Desktop> Get-MsolUser -UserPrincipalName steve@syfuhs.net | fl *

DisplayName                 : Steve Syfuhs
FirstName                   : Steve
ImmutableId                 :
LastName                    : Syfuhs
OverallProvisioningStatus   : Success
UserPrincipalName           : steve@syfuhs.net
ValidationStatus            : Healthy

The Immutable ID is a unique attribute that distinguishes a user in both on-premise Active Directory and Windows Azure Active Directory. Since I haven’t configured federation this value is blank.

Skip ahead a few pages after running the Convert-MsolDomainToFederated cmdlet and my domain is magically federated with my local Active Directory. If I re-run the first command we’ll see the Authentication attribute set to Federated. However, running the second command doesn’t return an Immutable ID and if I tried logging in through ADFS I get an error. What gives?

If we look at the token that is passed from ADFS to WAAD after sign in we see that there is actually a claim for an Immutable ID. This ID is what is used to determine the identity of the user, and if Office 365 has no idea who has that value it can’t trust that identity.

This particular problem is solved through directory synchronization using the DirSync service. DirSync is configured to get all users from Active Directory and add them to Windows Azure Active Directory. It synchronizes most attributes configured for a user including the objectGUID attribute. This attribute is synchronized to the ImmutableID attribute in WAAD. It’s the anchor that binds an on-premise user with a cloud user.

Two questions tend to arise from this process:

  1. Why not just use the UPN for synchronization?
  2. Why do you need to synchronize in the first place?

Both questions are fairly simple to answer, but the answers depend on one another. You cannot synchronize against a UPN because a user’s UPN can easily change. You need a value that will never change across the lifetime of a user account (hence the name “immutable”). You need the value to stay constant because synchronization will happen often. You need to synchronize any time a value changes in the on-premise Active Directory. Examples of changes include address changes or name changes. Changing your name can often result in changing your UPN.

It’s preferred to keep these attributes up to date in both systems because then applications can trust that they are getting the right values when requested from either system. This still begs the question though, why do you need to synchronize in the first place? Some people may ask this because it’s theoretically possible to provision new users as they first sign into an application. If the user doesn’t exist when they log in just create them. Simple.

The problem of course is that certain systems require knowledge of the user before the user ever logs in. A perfect example is Exchange. Imagine if a user is on vacation while the transition to Office 365 occurs. If the user doesn’t log in until they get back, that means they wouldn’t have received any email while they were away. Admittedly, not receiving a few weeks of email might be the preferred scenario for some, but I digress.

So we have to configure DirSync. Skip ahead a few more pages and DirSync executed and synchronized all my users. If we take a look back at my account we now see a value for the immutable ID:

PS C:\Users\Steve\Desktop> Get-MsolUser -UserPrincipalName steve@syfuhs.net | fl *

DisplayName                 : Steve Syfuhs
FirstName                   : Steve
ImmutableId                 : lHh/rEL830q6/mStDnD4uw==
UserPrincipalName           : steve@syfuhs.net
ValidationStatus            : Healthy

At this point I should now be able to log in.

If I navigate to https://portal.microsoftonline.com I’m redirected to https://login.microsoftonline.com and prompted for credentials. However, as soon as I type in my username it prompts telling me I have to go else where to sign in.

image

The sign in screen is smart enough to parse the domain name from my user and lookup the Authentication type tied to that domain. If the domain is configured as Federated the sign in page is told to redirect to ADFS. If we return back to that first PowerShell command we’ll see the authentication is set to Federated. This was set by the Convert-MsolDomainToFederated  command. Two things happened when it was called.

First, ADFS was configured to allow sending tokens to Windows Azure Active Directory. Second, WAAD was configured to receive tokens from ADFS.

We can take a look at exactly what was configured in WAAD by running more PowerShell.

PS C:\Windows\system32> Get-MsolDomainFederationSettings -DomainName syfuhs.net

ActiveLogOnUri         : << adfs server and username mixed endpoint >>
FederationBrandName    : syfuhs.net
IssuerUri              : urn:syfuhs:net
LogOffUri              : << adfs signout url >>
MetadataExchangeUri    : << adfs server mex endpoint >>
NextSigningCertificate :
PassiveLogOnUri        :
https://login.syfuhs/adfs/ls/
SigningCertificate     : MIICzDCCAbSgA.....sh37NMr5gpFGrUnnbFjuk9ATXF1WZ

I’ve stripped out a few things to make it a little more readable. The key is that PassiveLogOnUri field. That is the URL passed back to the sign in page and is what is used to compose a WS-Federation signin request.

If I click the link I’m redirected to ADFS and if the computer I’m using is a member of the same domain as ADFS I shouldn’t be prompted for credentials. After Windows Authentication does it’s thing ADFS determines that WAAD sent us because the wtrealm URL parameter is set to urn:federation:MicrosoftOnline which is WAAD's Audience URI.

When Convert-MsolDomainToFederated was called, ADFS was instructed to create a Relying Party Trust for WAAD. That trust had a set of claims issuance rules that query Active Directory for various things like a user’s objectGUID and UPN. These values are formatted, bundled into a SAML token, and signed with the ADFS signing key. The token is then POST’ed back to WAAD.

The SigningKey field we saw in the Get-MsolDomainFederationSettings command is the public key to the ADFS signing key. It was configured when Convert-MsolDomainToFederated was called. It is used to verify that the token received from ADFS is valid.  If the token is in fact valid the domain is located based on the Issuer URI and UPN, and the user is located in the domain. If a user is found then WAAD will create a new token for the user and issue it to whichever service initially requested login, which in our case is https://portal.microsoftonline.com.

From this point on any time I browse to an Office 365 service like Exchange, I’m redirected back to https://login.microsoftonline.com, and if my session is still valid from earlier, a new token is issued for Exchange. Same with SharePoint and Dynamics, Windows Intune, and any other application I’ve configured through Windows Azure Active Directory – even the Windows Azure management portal.

Federation with Office 365 through Windows Azure Active Directory is a very powerful feature and will be a very important aspect of cloud identity in the near future. While federation may seem like a complex black box, if we start digging into the configuration involved we start to learn a lot about the all the various moving parts, and hopefully realize its not too complex.

Introduction to Windows Azure Active Directory Federation Part 1

by Steve Syfuhs / November 30, 2012 12:19 AM

Earlier this week Microsoft released some interesting numbers regarding Windows Azure Active Directory (WAAD) authentication.

Since the inception of the authentication service on the Windows Azure platform in 2010, we have now processed 200 BILLION authentications for 50 MILLION active user accounts. In an average week we receive 4.7 BILLION authentication requests for users in over 420 THOUSAND different domains.

[…] To put it into perspective, in the 2 minutes it takes to brew yourself a single cup of coffee, Windows Azure Active Directory (AD) has already processed just over 1 MILLION authentications from many different devices and users around the world.  Not only are we processing a huge number of authentications but we’re doing it really fast!  We respond to 9,000 requests per second and in the U.S. the average authentication takes less than 0.7 seconds.

Whoa.

Now, some people may be wondering what this is all about. Where are all these requests coming from? What domains? Who? Huh? What? It’s actually pretty straightforward: 99.99999999% of all these requests are coming from Office 365 and Dynamics CRM.

Windows Azure Active Directory started as the authentication service for Office 365. The service is built on the Microsoft Federation Gateway, which is the foundation for Windows Live/Microsoft accounts. As the platform matured Microsoft opened the system to allow more applications to authenticate against the service. It has since transitioned into it’s proper name Windows Azure Active Directory.

The system at it’s core is simply a multitenant directory of users. Each tenant is tied to at least one unique domain. Each tenant can then allow applications to federate. This is basically how Office 365 works. When you create a new Office 365 account, the provisioning system creates a new tenant in WAAD and ties it to a subdomain of onmicrosoft.com, so you would for instance get contoso.onmicrosoft.com. Once the tenant is created the provisioning system then goes off to the various services you’ve selected like Exchange, SharePoint, CRM, etc and starts telling them to create their various things necessary for service. These services now know about your WAAD tenant.

This is all well and good, but you’re now using contoso.onmicrosoft.com, and you would rather use a different domain like contoso.com for email and usernames. Adding a domain to Office 365 requires telling both WAAD and the various services that a new domain is available to use in the tenant. Now WAAD has two domains associated with it.

Now we can create users with our custom domain contoso.com, but there’s like a thousand users and you have Active Directory locally. It would be much better if we could just log into Office 365 using our own Active Directory credentials, and it would be so much nicer on the administrator if he didn’t have to create a thousand users. This calls for federation between WAAD and AD through Active Directory Federation Services (too. many. AD-based. names!).

Things get a little more complicated here. Before looking at federation between WAAD and AD we should take a look at how authentication normally works in Office 365.

First a user will try to access an application like SharePoint. SharePoint doesn’t see a session for the user so it redirects the user to login.microsoftonline.com, which is the public face of Windows Azure Active Directory. The user enters their credentials managed through your WAAD tenant, and is then redirected back to SharePoint with a token. SharePoint consumes the token and creates a session for the user. This is a standard process called passive federation. The federation is between SharePoint and WAAD. SharePoint and the various other services trust login.microsoftonline.com (and only login.microsoftonline.com) to issue tokens, so when a user has a token issued by login.microsoftonline.com its understood that the user has been authenticated and is now trusted. Clear as mud, right?

Allowing authentication via your on premise Active Directory complicates things a little. This involves creating a trust between Windows Azure Active Directory and your Active Directory through a service called Active Directory Federation Services. A trust is basically a contract that states WAAD will understand and allow tokens received from ADFS. With this trust in place, any authentication requests to WAAD through login.microsoftonline.com will be passed to your ADFS server. Once your ADFS server authenticates you, a token is generated and sent back to login.microsoftonline.com. This token is then consumed, and a new token is generated by login.microsoftonline.com and issued to whichever service asked for you to log in. Remember what I said above: Office 365 services only trust tokens issued by login.microsoftonline.com. Everything flows through WAAD.

That was a pretty high-level discussion of how things work, but unfortunately it’s missing a few key pieces like DirSync. In my next post I’ll dive much deeper into the inner workings of all these bits and pieces explaining how Windows Azure Active Directory federates with your on premise Active Directory.

An Interesting Poll on ADFS and Office 365

by Steve Syfuhs / September 17, 2012 11:28 AM

As we prepared to launch a new product offering, Dana Epp decided to pose a question to some people on LinkedIn.

The question was simple: When you deployed ADFS and DirSync for Office 365 the first time, how long did it take you to get it working?

Here are the results (as of Monday morning, 9/17):

 

The first time I set it up, it took me about 3 days because at the time I had no clue what I was doing (insert joke here). This, I think, is the case for a lot of people as you can tell half the answers said either more than 3 days or it took too long.

On the flip side almost a quarter of the respondents said it took them about 4 hours. I wonder why?

What do you think? I’d love to hear your feedback in the comments below.

 

Talking ADFS on RunAs Radio

by Steve Syfuhs / December 01, 2011 07:02 PM

During the Toronto stop of the TechDays tour in Canada Richard Campbell was in town talking to a bunch of really smart people about the latest and greatest technologies they've been working on.

And then me for some reason.

We got to talk about ADFS and associates:

Richard talks to Steve Syfuhs at TechDays Toronto about IT Pros providing security services for developers using Active Directory Federated Services. IT and development talking to each other willingly? Perish the thought! But in truth, Steve makes it clear that ADFS provides a great wrapper for developers to access active directory or any other service that has security claims that an application might require. Azure depends on it, even Office 365 can take advantage of ADFS. Steve discusses how IT can work with developers to make the jobs of both groups easier.

You can listen to it here: http://www.runasradio.com/default.aspx?showNum=240

I need to work on using fewer vague analogies.

Adjusting the Home Realm Discovery page in ADFS to support Email Addresses

by Steve Syfuhs / July 12, 2011 04:00 PM

Over on the Geneva forums a question was asked:

Does anyone have an example of how to change the HomeRealmDiscovery Page in ADFSv2 to accept an e-mail address in a text field and based upon that (actually the domain suffix) select the correct Claims/Identity Provider?

It's pretty easy to modify the HomeRealmDiscovery page, so I thought I'd give it a go.

Based on the question, two things need to be known: the email address and the home realm URI.  Then we need to translate the email address to a home realm URI and pass it on to ADFS.

This could be done a couple ways.  First it could be done by keeping a list of email addresses and their related home realms, or a list of email domains and their related home realms.  For the sake of this being an example, lets do both.

I've created a simple SQL database with three tables:

image

Each entry in the EmailAddress and Domain table have a pointer to the home realm URI (you can find the schema in the zip file below).

Then I created a new ADFS web project and added a new entity model to it:

image

From there I modified the HomeRealmDiscovery page to do the check:

//------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------

using System;

using Microsoft.IdentityServer.Web.Configuration;
using Microsoft.IdentityServer.Web.UI;
using AdfsHomeRealm.Data;
using System.Linq;

public partial class HomeRealmDiscovery : Microsoft.IdentityServer.Web.UI.HomeRealmDiscoveryPage
{
    protected void Page_Init(object sender, EventArgs e)
    {
    }

    protected void PassiveSignInButton_Click(object sender, EventArgs e)
    {
        string email = txtEmail.Text;

        if (string.IsNullOrWhiteSpace(email))
        {
            SetError("Please enter an email address");
            return;
        }

        try
        {
            SelectHomeRealm(FindHomeRealmByEmail(email));
        }
        catch (ApplicationException)
        {
            SetError("Cannot find home realm based on email address");
        }
    }

    private string FindHomeRealmByEmail(string email)
    {
        using (AdfsHomeRealmDiscoveryEntities en = new AdfsHomeRealmDiscoveryEntities())
        {
            var emailRealms = from e in en.EmailAddresses where e.EmailAddress1.Equals(email) select e;

            if (emailRealms.Any()) // email address exists
                return emailRealms.First().HomeRealm.HomeRealmUri;

            // email address does not exist
            string domain = ParseDomain(email);

            var domainRealms = from d in en.Domains where d.DomainAddress.Equals(domain) select d;

            if (domainRealms.Any()) // domain exists
                return domainRealms.First().HomeRealm.HomeRealmUri;

            // neither email nor domain exist
            throw new ApplicationException();
        }
    }

    private string ParseDomain(string email)
    {
        if (!email.Contains("@"))
            return email;

        return email.Substring(email.IndexOf("@") + 1);
    }

    private void SetError(string p)
    {
        lblError.Text = p;
    }
}

 

If you compare the original code, there was some changes.  I removed the code that loaded the original home realm drop down list, and removed the code to choose the home realm based on the drop down list's selected value.

You can find my code here: http://www.syfuhs.net/AdfsHomeRealm.zip

Adding ADFS as an Identity Provider in ACS v2

by Steve Syfuhs / May 10, 2011 04:00 PM

Ever have one of those days where you swear that you've written something, but can't find it?  I could have sworn that I wrote this article before.  Ah well.

--

It makes a lot of sense to use ACS to manage Identity Providers.  It also makes sense to use Active Directory for letting users sign in to your cloud application.  Therefore we would hope that ACS and ADFS play nicely together.  It turns out they do.  in a previous post I talked about federating ACS and ADFS, where ACS is an identity provider to ADFS.  Now lets reverse it.  We want users to be redirected to ACS, then to ADFS to sign in.

First things first.  Lets log into our ACS namespace and navigate to the Identity Provider section, and then Add an Identity Provider:

image

From there we want to select what type of provider to use, and in this case we will select WS-Federation:

image

We are now provided with a form to fill out.  There are five properties: Display Name, WS-Federation metadata, Login Link text, Image Url, and Email domain names.

Display name is fairly straightforward.  What do you want the internal name of this IdP to be?

Next we need to provide a link to the Federation Metadata document that ADFS provides.  The path is https://adfs.domain.com/FederationMetadata/2007-06/FederationMetadata.xml.

Then we give it a public name, such as "ObjectSharp Internal Users".

If we want to use an image instead if showing text, we can provide a path to the image.

Finally we are asked for a semicolon separated list of email domains.  This may seem a bit confusing at first.  Basically, it allows us to filter out the IdP from the Home Realm Discovery page, and requires that the user enter in their email address.  That way, instead of seeing the "ObjectSharp Internal Users" link, we are provided a text box, where we need to enter an email address like ssyfuhs@objectsharp.com.  ACS will then look up the domain in their list, and if there is a reference to it, it will redirect to the IdP.

This takes care of the ACS bit.  just like in the previous post, you need to tell the other IdP about the other.  So we need to tell ADFS that ACS will be calling.  This is pretty simple.  We just need to add a relying party to ADFS using the ACS metadata.  You can find the ACS metadata under Application Integration:

image

There isn't much to federating ADFS to ACS and vice-versa.

Creating a Claims Provider Trust in ADFS 2

by Steve Syfuhs / April 25, 2011 04:00 PM

One of the cornerstones of ADFS is the concept of federation (one would hope anyway, given the name), which is defined as a user's authentication process across applications, organizations, or companies.  Or simply put, my company Contoso is a partner with Fabrikam.  Fabrikam employees need access to one of my applications, so we create a federated trust between my application and their user store, so they can log into my application using their internal Active Directory.  In this case, via ADFS.

So lets break this down into manageable bits. 

First we have our application.  This application is a relying party to my ADFS instance.  By now hopefully this is relatively routine.

Next we have the trust between our ADFS and our partner company's STS.  If the company had ADFS installed, we could just create a trust between the two, but lets go one step further and give anyone with a Live ID access to this application.  Therefore we need to create a trust between the Live ID STS and our ADFS server.

This is easier than most people may think.  We can just use Windows Azure Access Control Services (v2).  ACS can be set up very easily to federate with Live ID (or Google, Yahoo, Facebook, etc), so we just need to federate with ACS, and ACS needs to federate with Live ID.

Creating a trust between ADFS and ACS requires two parts.  First we need to tell ADFS about ACS, and second we need to tell ACS about ADFS.

To explain a bit further, we need to make ACS a Claims Provider to ADFS, so ADFS can call on ACS for authentication.  Then we need to make ADFS a relying party to ACS, so ADFS can consume the token from ACS.  Or rather, so ACS doesn't freak out when it see's a request for a token for ADFS.

This may seem a bit confusing at first, but it will become clearer when we walk through the process.

First we need to get the Federation Metadata for our ACS instance.  In this case I've created an ACS namespace called "syfuhs2".  The metadata can be found here: https://syfuhs2.accesscontrol.windows.net/FederationMetadata/2007-06/FederationMetadata.xml.

Next I need to create a relying party in ACS, telling it about ADFS.  To do that browse to the Relying party applications section within the ACS management portal and create a new relying party:

image

Because ADFS natively supports trusts, I can just pass in the metadata for ADFS to ACS, and it will pull out the requisite pieces:

image

Once that is saved you can create a rule for the transform under the Rule Groups section:

image

For this I'm just going to generate a default set of rules.

image

This should take care of the ACS side of things.  Next we move into ADFS.

Within ADFS we want to browse to the Claims Provider Trusts section:

image

And then we right-click > Add Claims Provider Trust

This should open a Wizard:

image

Follow through the wizard and fill in the metadata field:

image

Having Token Services that properly generate metadata is a godsend.  Just sayin'.

Once the wizard has finished, it will open a Claims Transform wizard for incoming claims.  This is just a set of claims rules that get applied to any tokens received by ADFS.  In other words, what should happen to the claims within the token we receive from ACS?

In this case I'm just going to pass any claims through:

image

In practice, you should write a rule that filters out any extraneous claims that you don't necessarily trust.  For instance, if I were to receive a role claim with a value "Administrator" I may not want to let it through because that could give administrative access to the user, even though it wasn't explicitly set by someone managing the application.

Once all is said and done, you can browse to the RP, redirect for authentication and will be presenting with this screen:

image

After you've made your first selection, a cookie will be generated and you won't be redirected to this screen again.  If you select ACS, you then get redirected to the ACS Home Realm selection page (or directly to Live ID if you only have Live ID).

Federated Authentication with ADP using ADFS 2

by Steve Syfuhs / March 31, 2011 04:00 PM

There's a great article over on the Ask the Directory Services Team blog on how to set up federation to ADP using ADFS 2.0.

I think we can all reach a general consensus that using ADFS as the identity provider makes federation pretty easy.  And awesome.

// About

Steve is a renaissance kid when it comes to technology. He spends his time in the security stack.