Thursday, January 07, 2016

OWIN : ASP.NET MVC application with multiple authentication options

There are many questions over at stackoverflow around this.

I have Forms Based Authentication (FBA) but I want to add other providers as well.

In WIF days, this was really difficult to do since WIF added events into the events pipeline.

With the advent of OWIN, this is a whole lot easier.

Assume you have ASP.NET Identity but you also want social (e.g. Facebook)  and WS-Fed and SAMLp. (p for the protocol as opposed to the token)

My starting point was Code! MVC 5 App with Facebook, Twitter, LinkedIn and Google OAuth2 Sign-on (C#).

I wasn't that interested in the social side - my interest was more the enterprise federation and I used Active Directory Federation services (ADFS) v3.0 as my IDP. This supports both WS-Fed and SAML.

The key point in creating the project is to leave "Change Authentication" as "Individual User Accounts". This gives you ASP.NET Identity as a starting point.

You need the following NuGet packages:

Microsoft.Owin.Security.WsFederation

Kentor.AuthServices

Kentor.AuthServices.Owin

The code in Startup.Auth.CS looks like:

// Uncomment the following lines to enable logging in with third party login providers

app.UseMicrosoftAccountAuthentication(
    clientId: "1234",
    clientSecret: "1234");

app.UseTwitterAuthentication(
    consumerKey: "1234",
    consumerSecret: "1234");

app.UseFacebookAuthentication(
    appId: "1234",
    appSecret: "1234");

app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
{
    ClientId = "1234",
    ClientSecret = "1234"
});

var adfs = new WsFederationAuthenticationOptions
{
    AuthenticationType = "Federation",
    Caption = "ADFS WS-Fed",
    
    MetadataAddress = "https://xxx/federationmetadata/2007-06/federationmetadata.xml",
    Wtrealm = "urn:owinmultirp"
};

app.UseWsFederationAuthentication(adfs);

var authServicesOptions = new KentorAuthServicesAuthenticationOptions(false)
{
    SPOptions = new SPOptions
    {
        EntityId = new EntityId("https://xxx/OWINMultiAuthWebApplication/saml/")
    },

    AuthenticationType = "KentorAuthServices",
    Caption = "ADFS - SAML2p",
};

Uri metadataURI = new Uri("https://xxx/federationmetadata/2007-06/federationmetadata.xml");

authServicesOptions.IdentityProviders.Add(new IdentityProvider(
    new EntityId("http://xxx/adfs/services/trust"),
    authServicesOptions.SPOptions)
    {
        MetadataUrl = metadataURI,
        LoadMetadata = true,
    });

app.UseKentorAuthServicesAuthentication(authServicesOptions);

You need the following includes:

    using Kentor.AuthServices;
    using Kentor.AuthServices.Owin;
    using System.IdentityModel.Metadata;

So there is just the one application but on the ADFS side we need to configure two RP; one for WS-Fed and one for SAML. Logically, ADFS thinks there are two separate applications.

There is no metadata so ADFS configuration has to be done manually.

ADFS WS-Fed

Set identifier to:

    urn:owinmultirp

Set endpoint to:

    https://xxx/OWINMultiAuthWebApplication/ or whatever for your app.


Set up claims rules as per IdentityServer : ASP.NET MVC application to idsrv3 to ADFS.

ADFS SAMLp

Set identifier to:

    https:/xxx/OWINMultiAuthWebApplication/saml/

Set endpoint as per:


Under the "Advanced" tab, set the "Secure Hash Algorithm" to SHA-1.

Set up claims rules as per IdentityServer : ASP.NET MVC application to idsrv3 to ADFS.

Just to reiterate - you must have a NameID claim for both protocols.

Login screen

Run up the application and you should see something like:


So now you have FBA plus a whole host of other options - all in the same application!

Enjoy!

6 comments:

Anders Abel said...

Thanks for posting, I've learnt a lot of ADFS interoperability from your posts.

Just a small comment on the metadata: AuthServices does expose metadata. In the example it would be on the https:/xxx/OWINMultiAuthWebApplication/AuthServices/ address. It is also a convention (but no requirement) to use that address as the EntityId, to make the metadata easier to find.

nzpcmad said...

Me bad! Yes - you could import this into ADFS.

The WS-Fed one doesn't have metadata though.

nzpcmad said...

"Can i get the source code of the example. I need to authenticate against ADFS and Shibboleth. Need guidance"

The code is in the link in the article (Code! MVC 5 App with Facebook, Twitter, LinkedIn and Google OAuth2 Sign-on (C#)) plus the changes I detailed in Startup.Auth.CS.

Unknown said...

Just a question, isn't there any library from microsoft that implements the protocol?
I mean my use case is quite common, I need to tweek my Service provider to be respond to IDP-initited SAMl.

am I wrong ? am I missing something?

Thanks

Unknown said...

Just a question, isn't there any library from microsoft that implements the protocol?
I mean my use case is quite common, I need to tweek my Service provider to be respond to IDP-initited SAMl.

am I wrong ? am I missing something?

Thanks

nzpcmad said...

No - there is no official Microsoft client-side SAML-P protocol stack.

There are other libraries - refer http://nzpcmad.blogspot.co.nz/2013/06/saml-saml-connectivity-toolkit.html.