Search code examples
owinasp.net-web-api2claims

OWIN Sharing claims between WebAPI and MVC Application


The current application that we are developing consists of 2 applications. A WebApi application, and a MVC frontend application. For the WebApi i added support for bearer token authorization via OWIN. These applications run as seperate websites within the same domain but with their own subdomains site.xxx.xxx, api.xxx.xxx

Authenticating to the WebAPi, f.e. with Postman, works as designed, the principal and identity objects, including the claims, are initialized properly.

The question arises when i want to login to the WEbApi from within the Mvc application.

Is there any way to get the ClaimsPrincipal and the ClaimsIdentity in our MVC application after logging in via the WebAPI via the /token url somewhat sharing the OWIN context, or should we implement the same OWIN authorization functionality inside the MVC application to create a seperate autorization "route"?


Solution

  • Yes, there is. Couple things to note

    • The token you get back from the web api will be encrypted by default. Your web application needs to decrypt this token to be able to extract the claims from the bearer token. For this, you have to have the same machine key on both of the servers (your webapi web.config and mvc web.config needs to have the same machine key)
    • Your MVC web app needs to wire up both bearer tokens and application cookies. Your startup.auth.cs might include something like this:

      public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; }
      
      static Startup()
      {
          OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
      }
      
      
      public void ConfigureAuth(IAppBuilder app)
      {
          app.UseOAuthBearerAuthentication(OAuthBearerOptions);
          app.UseCookieAuthentication(new CookieAuthenticationOptions
          {
              AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
              LoginPath = new PathString("/Account/Login")
          });
      }
      

      Now in your login method

      //Assume that the token that you got from web api is in the variable called accessToken
      //Decrypt this token first. If your machine keys are the same, the following line will work
      
      var unencryptedToken = Startup.OAuthBearerOptions.AccessTokenFormat.Unprotect(accessToken);
      
      //Next, extract the claims identity from the token
      var identity = unencryptedToken.Identity;
      
      //Need to create a claims identity that uses a cookie (not a bearer token). An MVC app 
      //knows how to deal with a claims identity using an application cookie, but doesn't know 
      //how to deal with a claims identity using a bearer token. So this is a translation step 
      //from a web api authentication mechanism to the mvc authentication mechanism
      
      var id = new ClaimsIdentity(identity.Claims, DefaultAuthenticationTypes.ApplicationCookie);
      
      //At this moment, your new claims identity using an application cookie is ready, but we still
      //need to sign in. Use the OWIN Auth manager from the context to sign in. This will create  
      //the application cookie and correctly populate User.IsAuthenticated(). From now on, you are 
      //logged in
      
      AuthenticationManager.SignIn(id);