Using Claims in your Web App is Easier with the new OWIN Security Components

Using Claims in your Web App is Easier with the new OWIN Security Components

Rate This
  • Comments 17

Hello everybody! My name is Vittorio Bertocci: I am a program manager in the Windows Azure Active Directory team, where I work on developer experience.

In the last few months the ASP.NET and Active Directory teams have been busy collaborating on a new OWIN-based programming model for securing modern ASP.NET applications. Today I have the privilege to announce the first developer preview of the OWIN components that will allow you to secure your ASP.NET applications with Windows Azure AD, ADFS and any other identity provider supporting WS-Federation.

Here there’s an image that gives some measure of the improvements we were able to achieve. On the left side, you can see a typical web.config file of an ASP.NET app configured to use claims based identity with current technology. On the right side, you can see the equivalent initialization logic when using the new OWIN components. Are you curious about how we got there? Read on! Smile

image

Claims Based Identity and the .NET Framework

Claims based identity made its debut in the developer’s toolbox back in 2009, with the first release of Windows Identity Foundation (WIF). At that time the only people working with claims based identity were individuals with both development and administration background, often leaning on the latter, with deep understanding of the underlying security protocols. The introduction of classes that took care of the low level details and Visual Studio tools to facilitate app configuration helped more and more developers to take advantage of claims’ ability to cross boundaries between platforms and between on-premises and cloud. With the release of .NET 4.5 in 2012 all the WIF classes migrated in the .NET Framework, with System.Security.Claims moving into mscorlib itself. Starting with the release of Visual Studio 2013, support for claims based identity is available directly in the project templates out of the box. And all the while, we’ve been updating the out of the box functionalities by releasing NuGet libraries implementing the latest industry advancements (such as support for new lightweight token formats).

Fast forward to today, claims based identity has gone completely mainstream. I have lost count of all the services and server products that take advantage of .NET’s rich support for claims and identity protocols.

image

Despite all of those advancements, however, the way in which web application developers interact with claims based identity has remained the same for all this time. The original design is web.config-heavy, as the administrators-developers of the time expected; it is based on HttpModules, tying it to apps based on the ASP.NET/IIS hosting; it exposes a lot of protocol-level information, empowering the protocol expert to control every aspect but requiring tools to generate the complex configuration files it needs; and so on.

It was time for us to go back and rethink how to make available the rich claims based identity capabilities of the .NET Framework in a modern, more effective way.

Enter Microsoft.Owin.Security.WsFederation

If you are following this space, you are already familiar with the Microsoft OWIN Components (Howard wrote a great introductory article here).
We already leveraged that framework in Visual Studio 2013 to deliver the next generation authentication components for Web API projects (see an introduction here). We got really good feedback on the approach we took there, which entails asking you via super simple initialization logic the absolute minimal amount of information required for securing your Web API. We decided to apply the same approach to browser-based sign on.

The .NET Framework already provides all of the raw functionality for processing claims based identity flows: token formats, cryptography, representation of the caller in form of ClaimsPrincipal… all those were already present and proven by half a decade of enterprise-grade use, hence we had no desire to replace those. We focused on the top layer of the stack, the one you need to touch directly when configuring your app to be secured using a claims based identity protocol, and re-implemented it using OWIN components.

image

Our JWT token handler library was already designed to work without web.config or HttpModules. We wanted the same for other assets, like the SAML token handlers, hence we created a very thin layer on top of those (the Microsoft.IdentityModel.Protocol.Extensions library).

Next, we extended Microsoft.Owin.Security to include base classes to be used for implementing standard web sign in protocols such as WS-Federation and OpenID Connect.

Finally, we created Microsoft.Owin.Security.WsFederation, a new component containing middleware for handling the WS-Federation protocol. We started with WS-Federation because that’s the most commonly supported protocol in our ecosystem today, allowing you to connect to both Windows Azure AD and ADFS from version 2.0 on. OpenId Connect support will come soon after.

You can get the packages above using the NuGet Package Manager Console with the following:

  • Install-Package Microsoft.Owin.Security.WsFederation -Version 3.0.0-alpha1 –Pre

Configuring your application to be secured via WS-Federation does not require you to use any tools, you just need to reference the right NuGet package and add some code similar to the following:

public void ConfigureAuth(IAppBuilder app)
{
    app.UseCookieAuthentication(
        new CookieAuthenticationOptions
        {
            AuthenticationType = 
               WsFederationAuthenticationDefaults.AuthenticationType
        });

    app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions
        {
            MetadataAddress = "https://login.windows.net/azurefridays.onmicrosoft.com/federationmetadata/2007-06/federationmetadata.xml",
            Wtrealm = "http://myapps/WsFed_AAD1",
        });
}

Most of it is absolutely boilerplate code, that will look the same in all of your projects. The only parts that will change are:

  • MetadataAddress. This value represents the Windows Azure AD tenant (or ADFS instance) you want to use for authenticating your users. If you are writing line of business apps for your own company, this line will likely never change.
  • Wtrealm. This is the identifier of your application, as assigned when you configured your app in your authenticating authority (in the Windows Azure portal for Windows Azure AD, in the management console for ADFS).

… and that’s all you need!

Besides being significantly easier to program against, the new approach has many more advantages:

  • It is now possible to combine multiple authentication types in a single application. For example, you could have some routes serve web UX and some others handle Web API calls – and have the former secured via WS-Federation while the latter are secured via OAuth2 bearer tokens. Owin makes it very straightforward!
  • It’s now very easy to use claims-based identity in self hosted scenarios

Same Expressive Power for Advanced Uses

Making the easy cases easy was an area where the HttpModule-based approach wasn’t great: we believe the OWIN approach improved that.

However we did not want to lose the flexibility and expressive power that made possible the big success of claims based identity: hence we build on the experience of half a decade of observing developers use the current extensibility model, and ensured that equivalent affordances are available in the new components. Where possible, we consolidated by eliminating parts that weren’t used and improved on scenarios that needed better support.

I will be posting various deep dives on www.cloudidentity.com in the next few days, but just to give you a taste: the wsFederationAuthenticationOptions class referenced above can either be initialized with minimal amount of info (as shown above) or it can be used to specify finer grained settings. You can control most aspects of the protocol and inject your own custom logic (via delegates) at key stages of the validation pipeline. If you are familiar with the protocol and/or the current extensibility model, you might see some furniture rearranged but mostly you should feel right at home.

image

An Example: Securing an MVC App with Windows Azure AD

See this blog post where I provide step by step instructions on securing a MVC app with Windows Azure AD.

Next Steps

We are very, very excited to make this preview available to you, and we can’t wait to hear what you think about it! At this phase your feedback is absolutely crucial. If you want to join the conversation, there are plenty of ways for you to do so:

As mentioned above, I’ll be posting various deep dives on www.cloudidentity.com – if there are specific scenarios you want to see covered, please make sure you use the channels above to let us know and we’ll do our best to prioritize accordingly.

Thanks and enjoy!

Leave a Comment
  • Please add 2 and 8 and type the answer here:
  • Post
  • Does this support ACS or asp.net identity or does it require more work first?

  • I am happy to be here and I study more and more to get here

  • Hi Betty,

    this middleware does work with ACS. You need to pass the metadata of your namespace, something like https://<yournamespace>.accesscontrol.appfabriclabs.com/FederationMetadata/2007-06/FederationMetadata.xml.

    Also note, though: ACS is no longer being updated, and its features will move to Windows Azure AD. See blogs.technet.com/.../azure-active-directory-is-the-future-of-acs.aspx

  • Thanks Vittorio.  I was aware of ACS being deprecated, unfortunately WAAD doesn't easily support a custom STS or external Identity providers.  Really wanting Asp.net identity/stackoverflow style multi login support for o365

  • Hi,

    I'm trying to use Security.WsFederation and Security.ActiveDirectory in the same ASP.NET application. I've installed the latest versions (prerelease) of above components from NuGet. WsFederation works fine, however ActiveDirectory does not. I get the following error from OWIN:

    <code>

    Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationMiddleware Error: 0 : Authentication failed

    System.MissingMethodException: Method not found: 'Void System.IdentityModel.Tokens.TokenValidationParameters.set_AllowedAudiences(System.Collections.Generic.IEnumerable`1<System.String>)'.

      at Microsoft.Owin.Security.Jwt.JwtFormat.Unprotect(String protectedText)

      at Microsoft.Owin.Security.Infrastructure.AuthenticationTokenReceiveContext.DeserializeTicket(String protectedData)

      at Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationHandler.<AuthenticateCoreAsync>d__0.MoveNext()

    </code>

    I was able to find out that that WsFederation requires a newer version (4.0.0.0) of 'System.IdentityModel.Tokens.Jwt' in which TokenValidationParameters.AllowedAudiences was changed to TokenValidationParameters.ValidAudiences and I think that that is why Security.ActiveDirectory does not work with new version of 'System.IdentityModel.Tokens.Jwt'. Will there be a new version of Security.ActiveDirectory that supports v4 of 'System.IdentityModel.Tokens.Jwt' available soon, or is it possible to use both asemblies in the same ASP.NET application?

  • Hi Jure,

    thanks for trying the bits out! You stumbled on a known issue, sorry about that. It will be fixed in the next update.

    Thanks

    V.

  • Hi Vittorio,

    Thanks for the quick reply. Is there any news available on when there will be a next update?

  • Can I use OWIN to programmatically validate a SAML token, instead of configuration based? I am accepting SAML token in a header and I need to validate the SAML token, can I do that with OWIN?

  • How do I specify the serviceCertificate\serviceReference in a RP for a custom STS that requires encrypting credentials with this OWIN middleware?

    Thanks.

  • Hi,

    I managed to use the middleware to secure an MVC project. I then tried to add a WebAPI controller to get the API controller to use the authentication cookie, but after logging in, any attempt to call a web api controller fails with the following message:

    "Unable to read the entity body. A portion of the request stream has already been read."

    Am I doing something wrong in the code? or is this a known issue?

  • I've finally managed to get WsFederation working along with CookieAuthentication in the same application...just not at the same time. The WsFederation sample implementation sets up "UseCookieAuthentication" with the default CookieAuthenticationOptions. This works for Federation but not for the other. If I comment that out and use the sample code for UseCookieAuthentication (which setups AuthenticationType, LoginPath, and Provider), then it works but WsFederation no longer works.

    Any ideas?

  • Update...so WsFederation uses "Cookies", and local user accounts uses "ApplicationCookie". Apparently, never the 'twain shall meet. Sigh. Two days work down the drain.

  • And the final update, in case anyone else is having this issue: the solution is to call app.UseCookieAuthentication TWICE, specifying ApplicationCookie for local auth and leaving the AuthenticationType to default (CookieAuthenticationDefaults.AuthenticationTypes) for WsFed.

  • Hi,

    I want to use SAML 2.0 as tokenprovider, and OpenID, ADFS etc.. How can I set this up with OWIN? My first interest goes in how to setup SAML 2.0 federation.

    J.

  • Hi,

    I have a MVC 5 app and a Web API 2 app. I want to get OAuth token from STS provider during Singing and use the token for cal the apis that host in another domain.

    It is possible?

    Best,

Page 1 of 2 (17 items) 12