Byron Jones Byron Jones - 23 days ago 8
ASP.NET (C#) Question

Ws-Federation Identity Information Not Available in Web API?

I'm using Ws-Fed Authentication OWIN middleware to authenticate an ASP.NET MVC app with Web API endpoints using ADFS. I'm able to sign in using ADFS successfully, and on my MVC controllers, HttpContext.User.Identity.IsAuthenticated is true - I can see the claims information for the signed in user as well.

However for WebAPI endpoints, User.Identity.IsAuthenticated is false. The claims information for the signed is user is also unavailable. Is there any way that I expose the fact that the user is authenticated for both MVC and WebAPI controllers?

Here is how I am configuring my authentication middleware in the OWIN Startup class:

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
ExpireTimeSpan = TimeSpan.FromMinutes(sessionDuration),
SlidingExpiration = true //expiration extended after each request
});

app.UseWsFederationAuthentication(
new WsFederationAuthenticationOptions
{
Wtrealm = realm,
MetadataAddress = metadata,
Notifications = new WsFederationAuthenticationNotifications
{
AuthenticationFailed = context =>
{
context.HandleResponse();
context.Response.Redirect("/?loginfailed=loginfailed");
return Task.FromResult(0);
}
}
});

Answer

So I discovered the answer to this question by examining the OWIN cookie authentication middleware source code on CodePlex. Cookies created using the middleware by an MVC controller are created differently from cookies created Web API. MVC cookies are a reference to user information stored in session, and since Web API is completely stateless (no session), cookies created in MVC can not be used in Web API.

In addition, it is bad practice to use cookie authentication in Web API anyways; bearer token authentication is a preferable option.

In my case where I needed to use Ws-Federation authentication, the solution was to:

  1. Add bearer token authentication middleware to my app

  2. Create a Web API endpoint (ideally cryptically named) that will securely receive Ws-Federation claims, perform validation to ensure the request really came from your MVC controller, use them to generate a bearer token, and respond with the generated bearer token

  3. Upon authenticating in MVC, serialize the claims, and marshal them over to Web API using the endpoint created earlier

  4. Add the bearer token to a hidden field in the SPA

Many, many thanks to @Juan for providing me with feedback and links to point me in the right direction.

Comments