Windows Azure ACS v2 Mix Announcement

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

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…

Really?

image

No.  Really.  I can't.

Sigh.

And in Other News...

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

Federated Authentication with ADP using ADFS 2

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.

Azure At the Movies on May 5th

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

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

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

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(); }

Windows Domain Authentication on Windows Phone 7

One of the projects that’s been kicking around in the back of my head is how to make Windows Phone 7 applications able to authenticate against a Windows domain.  This is a must have for enterprise developers if they want to use the new platform.

There were a couple ways I could do this, but keeping with my Claims-shtick I figured I would use an STS.  Given that ADFS is designed specifically for Active Directory authentication, I figured it would work nicely.  It should work like this:

image

Nothing too spectacularly interesting about the process.  In order to use ADFS though, I need the correct endpoint.  In this case I’m using

https://[external.exampledomain.com]/adfs/services/Trust/13/usernamemixed

That takes care of half of the problem.  Now I actually need to make my application call that web service endpoint. 

This is kind of a pain because WP7/Silverlight don’t support the underlying protocol, WS-Federation.

Theoretically I could just add that endpoint as a service reference and build up all the pieces, but that is a nightmare scenario because of all the boiler-plating around security.  It would be nice if there was a library that supported WS-Federation for the phone.

As it turns out Dominick Baier came across a solution.  He converted the project that came from the Identity training kit initially designed for Silverlight.  As he mentions there were a few gotchas, but overall it worked nicely.  You can download his source code and play around.

I decided to take it a step further though.  I didn’t really like the basic flow of token requests, and I didn’t like how I couldn’t work with IPrincipal/IIdentity objects.

First things first though.  I wanted to start from scratch, so I opened the identity training kit and looked for the Silverlight project.  You can find it here: [wherever you installed the kit]\IdentityTrainingKitVS2010\Labs\SilverlightAndIdentity\Source\Assets\SL.IdentityModel.

Initially I thought I could just add it to a phone project, but that was a bad idea; there were too many build errors.  I could convert the project file to a phone library, but frankly I was lazy, so I just created a new phone library and copied the source files between projects.

There were a couple references missing, so I added System.Runtime.Serialization, System.ServiceModel, and System.Xml.Linq.

This got the project built, but will it work?

I copied Dominick’s code:

WSTrustClient _client;

private void button1_Click(object sender, RoutedEventArgs e)
{
    _client = GetWSTrustClient(
https://[...]/adfs/services/Trust/13/usernamemixed,
new UsernameCredentials("username", "password")); var rst = new RequestSecurityToken(WSTrust13Constants.KeyTypes.Bearer) { AppliesTo = new EndpointAddress("[…]") }; _client.IssueCompleted += client_IssueCompleted; _client.IssueAsync(rst); } void client_IssueCompleted(object sender, IssueCompletedEventArgs e) { _client.IssueCompleted -= client_IssueCompleted; if (e.Error != null) throw e.Error; var token = e.Result; button2.IsEnabled = true; } private WSTrustClient
GetWSTrustClient(string stsEndpoint, IRequestCredentials credentials) { var client = new WSTrustClient(new WSTrustBindingUsernameMixed(),
new EndpointAddress(stsEndpoint), credentials); return client; }

To my surprise it worked.  Sweet.

This left me wanting more though.  In order to access any of the claims within the token I had to do something with the RequestSecurityTokenResponse (RSTR) object.  Also, how do I make this identity stick around within the application?

The next thing I decided to do was figure out how to convert the RSTR object to an IClaimsIdentity.  Unfortunately this requires a bit of XML parsing.  Talk about a pain.  Helper class it is:

public static class TokenHandler
{
    private static XNamespace ASSERTION_NAMESPACE 
= "urn:oasis:names:tc:SAML:1.0:assertion"; private const string CLAIM_VALUE_TYPE
= "http://www.w3.org/2001/XMLSchema#string"; // bit of a hack public static IClaimsPrincipal Convert(RequestSecurityTokenResponse rstr) { return new ClaimsPrincipal(GetClaimsIdentity(rstr)); } private static ClaimsIdentity GetClaimsIdentity(RequestSecurityTokenResponse rstr) { XDocument responseDoc = XDocument.Parse(rstr.RequestedSecurityToken.RawToken); XElement attStatement = responseDoc.Element(ASSERTION_NAMESPACE + "Assertion")
.Element(ASSERTION_NAMESPACE + "AttributeStatement"); var issuer = responseDoc.Root.Attribute("Issuer").Value; ClaimCollection claims = new ClaimCollection(); foreach (var c in attStatement.Elements(ASSERTION_NAMESPACE + "Attribute")) { string attrName = c.Attribute("AttributeName").Value; string attrNamespace = c.Attribute("AttributeNamespace").Value; string claimType = attrNamespace + "/" + attrName; foreach (var val in c.Elements(ASSERTION_NAMESPACE + "AttributeValue")) { claims.Add(new Claim(issuer, issuer, claimType,
val.Value, CLAIM_VALUE_TYPE)); } } return new ClaimsIdentity(claims); } }

Most of this is just breaking apart the SAML-goo.  Once I got all the SAML assertions I generated a claim for each one and created a ClaimsIdentity object.  This gets me a step closer to how I wanted things, but keeping the identity around within the application is still up in the air.  How can I keep the identity for the lifetime of the application?  I wanted something like Thread.CurrentPrincipal but the phone platform doesn’t let you access it.

There was a class, TokenCache, that was part of the original Silverlight project.  This sounded useful.  it turns out it’s Get/Add wrapper for a Dictionary<>.  It’s almost useful, but I want to be able to access this cache at any time.  A singleton sort of solves the problem, so lets try that.  I added this within the TokenCache class:

public static TokenCache Cache
{
    get
    {
        if (_cache != null)
            return _cache;

        lock (_sync)
        {
            _cache = new TokenCache();
        }

        return _cache;
    }
}

private static TokenCache _cache;
private static object _sync = new object();

 

now I can theoretically get access to the tokens at any time, but I want to make the access part of the base Application object.  I created a static class called ApplicationExtensions:

public static class ApplicationExtensions
{
    public static IClaimsPrincipal 
GetPrincipal(this Application app, string appliesTo) { if (!TokenCache.Cache.HasTokenInCache(appliesTo)) throw new ArgumentException("Token cannot be found to generate principal."); return TokenHandler.Convert(TokenCache.Cache.GetTokenFromCache(appliesTo)); } public static RequestSecurityTokenResponse
GetPrincipalToken(this Application app, string appliesTo) { return TokenCache.Cache.GetTokenFromCache(appliesTo); } public static void
SetPrincipal(this Application app, RequestSecurityTokenResponse rstr) { TokenCache.Cache.AddTokenToCache(rstr.AppliesTo.ToString(), rstr); } }

 

It adds three extension methods to the base Application object.  Now it’s sort of like Thread.CurrentPrincipal.

How does this work?  When the RSTR is returned I can call:

Application.Current.SetPrincipal(rstr);
 

Accessing the identity is two-part.

If I just want to get the identity and it’s claims I can call:

var principal = Application.Current.GetPrincipal("https://troymcclure/webapplication3/");

IClaimsIdentity ident = principal.Identity as IClaimsIdentity;
 

If I want to reuse the token as part of web service call I can get the token via:

var token = Application.Current.GetPrincipalToken(https://troymcclure/webapplication3/);
 

There is still quite a lot to do in order for this to be production ready code, but it does a pretty good job of solving all the problems I had with domain authentication on the Windows Phone 7 platform.