C# – using wif with web api

asp.net-mvc-4asp.net-web-apicnetrest

I got lots of articles and SO question based on Claim based authentication for WCF Restful Services, but I am using MVC Web API to develop RESTful Service (Not WCF Rest Service)…

So could you please help me to understand how to secure RESTful service using claim based authentication?

Here is what I need:

  1. I have a Web App and MVC4 Web-API service
  2. We have STS
  3. The MVC Web App trusts the STS
  4. Now the user logs into the Web App, he is redirected to the STS login page.
  5. Once logged in, he is redirected back to the MVC Web Site.
  6. This web app invokes the web-API Service.

Now, I have been stuck at point #4. We have a RESTful service, but need to implement WIF.

Can anyone please help me with this.

Note: I am NOT using WCF Restservice but using MVC Web API

Best Answer

From your description, it sounds like you are using a delegated identity model. That is, the user signs in to the web application and when the web application invokes the Web API service, it uses the identity of the currently logged in user.

If that is the case, then you need to configure WIF to save the "bootstrap tokens". The effect of this is that the original security token is available as a property on the current ClaimsIdentity. you can then use that to set the Authorize header of he request to the Web API service call.

To turn this on in .Net 4.5 you set the saveBootstrapContext attribute on the WIF element to true:

<system.identityModel>
   <identityConfiguration saveBootstrapContext="true">
   ...

For .Net 4, the config looks lke this:

<microsoft.identityModel>
   <service saveBootstrapTokens="true">
   ...

Then to access it from the web application you do something like (depending on how many identities you have) this in the controller that is going to call the Web API. For .Net 4.5:

SecurityToken token = (User as ClaimsPrincipal).Identities[0].BootstrapContext;

For .Net 4:

SecurityToken token = (User as ClaimsPrincipal).Identities[0].BootstrapToken;

Having obtained the original security token, you can now attach it to the calls to the Web API as an Authorize header. Generally this will be attached as a Bearer token, which is just a fancy way of saying that you append the word "bearer" to the start of the header value. To attach the token, do something like this:

WebClient request = new WebClient();
request.Headers.Add("Authorization","bearer " + tokenAsString); 

Note: Generally you will encrypt or base64 encode the token value in transit rather than attach the raw string, especially if it is XML, since some frameworks will mangle the XML in transit.

To convert the token to a string, you should user a class derived from SecurityTokenHandler There are a number of these included in the standard framework assemblies for handling some standard token types. For REST services, the JSON Web Token is a popular format and there is a NuGet package containing a handler for that here

https://www.nuget.org/packages/System.IdentityModel.Tokens.Jwt/

If you are using some other token type, you can write your own handler (it is not difficult in fact) or try to find on on the web.

In .Net 4.5 the SecurityTokenHandler class has a WriteToken(SecurityToken) method that returns the token as a string. In earlier versions of WIF only the XML version of WriteToken was supported.

There are several samples showing how to use the SecurityTokenHandler for REST services on the server side. A good example is here

http://code.msdn.microsoft.com/AAL-Native-App-to-REST-de57f2cc/view/Discussions#content

All the relevant code is contained in the global.asax.cs file.