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

// steve

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).

Windows Azure Access Control Services Federation with Facebook

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

Sometime in the last few years Facebook has gotten stupidly popular.  Given the massive user base, it actually makes a little bit of sense to take advantage of the fact that you can use them as an identity provider.  Everyone has a Facebook account (except… me), and you can get a fair bit of information out of it on the user.

The problem though is that it uses OpenAuth, and I, of course, don't like OpenAuth.  This makes it very unlikely for me to spend any amount time working with the protocol, and as such wouldn't jump at the chance to add it into an application.  Luckily ACS supports Facebook natively – AND it's easy to setup.

First things first, we need to log into our ACS management portal, and select Identity Providers under Trust Relationships.  Then we need to add a new Identity Provider:

image

Then we need to select Facebook as the type we want to add:

image

Once we start filling out the details for the federation we need to get some things from Facebook directly.

image

There are three fields we need to worry about, Application ID, Application secret, and Application permissions.  We can get the first two from the settings page of our Facebook application, which you can get to at www.facebook.com/developers/.

You should create a separate application for each instance you create, and I'll explain why in a minute.

You then need the Application permissions.  This is a list of claims to request access to from Facebook.  The full list can be found here: http://developers.facebook.com/docs/authentication/permissions/, but for now email will suffice.

Once you have saved this identity provider you need to create a rule for each relying party.  This will define how the claims are transformed before being sent to your relying party. If you already have rules set up you can modify one:

image

I'm pretty content with just using the default rules, which is to just pass everything, but you need to generate them first:

image

image

Once the rules have been generated you can save the rule.

Now you can test the federation.

It should fail.

If you watched everything in Fiddler you will see a chunk of JSON returned that looks something like:

{
   "error": {
      "type": "OAuthException",
      "message": "Invalid redirect_uri: Given URL is not allowed by the Application configuration."
   }
}

This is about my warning earlier about creating a separate application for each ACS namespace.  Basically, Facebook doesn't like the request for authentication because it has no idea who the requestor is.  Therefore I need to tell Facebook about my application.

To do this you need to get into the Web site settings for your application Facebook:

image

You will need to set the Site URL property to the ACS namespace:

image

Given the requirement for the FQDN, you need to create an application for each namespace you decide to create.

At this point federation with Facebook should now work.  If you are using the default login page you should see something like this:

image

And if you sign-in you should get a token from Facebook which ACS will normalize, and then return to your relying party.  Based on the permissions request you set above you should see something this:

image

** UPDATE **

Some of you may be wondering about this AccessToken claim.  Part of the ACS configuration asks for a set of permissions to request, and these permissions are tied to this access token.  Instead of receiving everything within claims, you need to make a separate call to Facebook to get these details by using the access token.

Dominick Baier has a good article explaining how to accomplish this: http://www.leastprivilege.com/AccessControlServiceV2AndFacebookIntegration.aspx.

** END UPDATE **

For those of you who want to federate with Facebook but don't like the idea of writing OpenAuth goo, ACS easily simplifies the process.

Windows Azure ACS v2 Mix Announcement

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

Part of the Mix11 announcement was that ACS v2 was released to production.  It was actually released last Thursday but we were told to keep as quiet as possible so they could announce it at Mix.  Here is the marketing speak:

The new ACS includes a plethora of new features that customers and partners have been asking with enthusiasm: single sign on from business and web identity providers, easy integration with our development tools, support for both enterprise-grade and web friendly protocols, out of the box integration with Facebook, Windows Live ID, Google and Yahoo, and many others.

Those features respond to such fundamental needs in modern cloud based systems that ACS has already become a key asset in many of our own offerings.

There is a substantial difference between v1 and v2.  In v2, we now see:

Federation provider and Security Token Service (FINALLY!)

  • Out of box federation with Active Directory Federation Services 2.0, Windows Live ID, Google, Yahoo, Facebook

New authorization scenarios

  • Delegation using OAuth 2.0

Improved developer experience

  • New web-based management portal
  • Fully programmatic management using OData
  • Works with Windows Identity Foundation

Additional protocol support

  • WS-Federation, WS-Trust, OpenID 2.0, OAuth 2.0 (Draft 13)

That's a lot of stuff to keep up with, but luckily Microsoft has made it easier for us by giving us a whole whack of content to learn from.

First off, all of the training kits have now been updated to support v2:

Second, there are a bunch of new Channel9 videos just released:

Third, and finally, the Claims Based Identity and Access Control Guide was updated!

Talk about a bunch of awesome stuff.

Windows Azure Access Control Services v2 RTW

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

So how do you know when Windows Azure Access Control Services has upgraded to V2?  You get federation metadata…

image

Or you follow the Windows Azure App Fabric team blog!

I have been waiting MONTHS for this release, begging and pleading with Microsoft to get more information on when the big day would come.  Needless to say I am super excited!

This version adds:

Federation provider and Security Token Service (FINALLY!)

  • Out of box federation with Active Directory Federation Services 2.0, Windows Live ID, Google, Yahoo, Facebook

New authorization scenarios

  • Delegation using OAuth 2.0

Improved developer experience

  • New web-based management portal
  • Fully programmatic management using OData
  • Works with Windows Identity Foundation

Additional protocol support

  • WS-Federation, WS-Trust, OpenID 2.0, OAuth 2.0 (Draft 13)

Now to just migrate from Appfabric Labs…

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.

And in Other News...

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

Got this email earlier today:

Dear Steve Syfuhs,
Congratulations! We are pleased to present you with the 2011 Microsoft® MVP Award! This award is given to exceptional technical community leaders who actively share their high quality, real world expertise with others. We appreciate your outstanding contributions in Developer Security technical communities during the past year.

[…] 

Needless to say I'm super excited about this award, and the opportunity that it gives me to talk more about security.  More on this later.

Now I just need to figure out what to put in my email signature. Winking smile

Azure At the Movies on May 5th

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

It's the event everyone has waited for all year! Well. Maybe between the time that we first announced we were doing it again, and well, now. But, here we go again!

Every year ObjectSharp puts on an At the Movies event showcasing the latest and greatest technologies we have determined to be pretty awesome.

Register Now!


Objectsharp

What it's about

Join ObjectSharp and Microsoft on May 5th for a Half Day in the Cloud! Learn to provide stability and elasticity for your web based solutions as we build to leverage Windows Azure. Technologies including Silverlight, ASP.NET MVC, Team Foundation Server, Visual Studio and Powershell will be in the Air as we rain data down from the Cloud. This is one summer blockbuster event that cannot be missed!

This event is for you if:

  • You’re responsible for Web Based or Web Deployed Applications
  • You’re looking to provide better test coverage for your Applications
  • You’re on-premise servers are starting to reach capacity [or ready to catch fire]
  • You don’t want to get left behind…

Registration is filling really quickly (like really, really, really quickly), so Register Now!

Plugging Application Authentication Leaks in ADFS

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

When you set up ADFS as an IdP for SAML relying parties, you are given a page that allows you to log into the relying parties.  There is nothing particularly interesting about this fact, except that it could be argued that the page allows for information leakage.  Take a look at it:

image

There are two important things to note:

  • I'm not signed in
  • I can see every application that uses this IdP

I'm on the fence about this one.  To some degree I don't care that people know we use ADFS to log into Salesforce.  Frankly, I blogged about it.  However, this could potentially be bad because it can tell an attacker about the applications you use, and the mechanisms you use to authenticate into them.

This is definitely something you should consider when developing your threat models.

Luckily, if you do decide that you don't want the applications to be visible, you can make a quick modification to the IdpInitiatedSignOn.aspx.cs page.

There is a method called SetRpListState:

protected void SetRpListState( object sender, EventArgs e )
{
    RelyingPartyDropDownList.Enabled = OtherRpRadioButton.Checked;
    ConsentDropDownList.Enabled = OtherRpRadioButton.Checked;
}

To get things working I made two quick modifications.  First I added the following line of code to that method:

OtherRpPanel.Visible = this.IsAuthenticated;

Then I added a line to the Page_Init method:

SetRpListState(null, null);

Now unauthenticated users just see this:

image

And authenticated users see everything as expected:

image

You could extend this further and add some logic to look into the App Settings in the web.config to quickly and easily switch between modes.

AzureFest Revisited

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

Remember a few months ago when ObjectSharp and Microsoft put on AzureFest at the Microsoft office in Mississauga?  Well, here we go again!  This time we have two events:

  • Downtown Toronto: March 30th, 2011 – MSN Office, 222 Bay Street
  • Mississauga: March 31st, 2011 – Microsoft Canada HQ, 1950 Meadowvale Blvd

Our presenter for both evenings is Cory Fowler, and he is the Canadian MVP for Windows Azure, an ObjectSharp Consultant, and a good friend of mine.

You can register by clicking here.

What you’ll learn

  • How to setup your Azure Account
  • How to take a traditional on-premise ASP.NET applications and deploy it to Azure
  • Publishing Applications to Azure Developer Portal
  • Setting up the Azure SDK and Azure Tools for Visual Studio on your laptop
  • using the development App Fabric

We provide

  • The tools you will need on your machine to prepare yourself for Azure
  • Hands on instruction and expert assistance
  • Power and network access
  • Snacks and refreshments
  • For every azure activation – funding for your User Group
  • Post event technical resources so you can take your skills to the next level

You provide

  • Your own laptop
  • Your own credit card (for Azure activations this is required, even if you only setup for a trial period, but this event is free!)
  • Your experience in building ASP.NET Applications and Services

Seats are still available. Register!

You know you want to register… Smile

P.S. Did I mention this event is free?

Claims Authentication Helper Class for the Windows Phone 7

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

The other day I talked about doing Windows Authentication within a Windows Phone 7 application.  I wanted to make it a simpler process so I created a helper class to do this:

public static class ClaimsAuthentication
{
    static WSTrustClient client;

    public static class Endpoints
    {
        public const string AdfsAuthentication = "/adfs/services/trust/13/usernamemixed";
    }

    public static void AuthenticateAsync(string endpoint, 
IRequestCredentials credentials,
string appliesTo) { client = GetWSTrustClient(endpoint, credentials); var rst = new RequestSecurityToken(WSTrust13Constants.KeyTypes.Bearer) { AppliesTo = new EndpointAddress(appliesTo) }; client.IssueCompleted += client_IssueCompleted; client.IssueAsync(rst); } private static void client_IssueCompleted(object sender, IssueCompletedEventArgs e) { client.IssueCompleted -= client_IssueCompleted; if (e.Error == null) Application.Current.SetPrincipal(e.Result); IssueCompleted(sender, e); } public static event EventHandler<IssueCompletedEventArgs> IssueCompleted; private static WSTrustClient GetWSTrustClient(string stsEndpoint,
IRequestCredentials credentials) { return new WSTrustClient(new WSTrustBindingUsernameMixed(),
new EndpointAddress(stsEndpoint), credentials); } }

You can call it like this:

private void button1_Click(object sender, RoutedEventArgs e)
{
    if (!CheckCredentials())
    {
        MessageBox.Show("Credentials Are Missing.");
        return;
    }

    string endpoint = string.Format("https://{0}{1}", "adfs.example.com", 
ClaimsAuthentication.Endpoints.AdfsAuthentication); ClaimsAuthentication.IssueCompleted += new EventHandler
<IssueCompletedEventArgs>(ClaimsAuthenticationHelper_IssueCompleted); ClaimsAuthentication.AuthenticateAsync(endpoint,
new UsernameCredentials(“user”, “pass”),
"urn:someapp:blah"); } void ClaimsAuthenticationHelper_IssueCompleted(object sender, IssueCompletedEventArgs e) { if (e.Error != null) { showError(e.Error); return; } DoSomething(); }

// About

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