Click here to Skip to main content
14,113,296 members
Click here to Skip to main content
Add your own
alternative version


9 bookmarked
Posted 7 Aug 2014
Licenced MIT

Common Authentication/Authorization Between .NET4.0 and .NET4.5 Web Applications

, 7 Aug 2014
Rate this:
Please Sign up or sign in to vote.
Common Authentication/Authorization between .NET4.0 and .NET4.5 Web Applications

ASP.NET Identity is a big step forward and we should profit from its features, such as: two-step authentication, support for OpenId providers, stronger password hashing and claims usage. One of its requirements is .NET4.5 which might be a blocker if you have in your farm legacy Windows 2003 R2 servers still hosting some of your MVC4 (.NET4.0) applications. In this post, I would like to show you how you may implement common authentication and authorization mechanisms between them and your new ASP.NET MVC5 (and .NET4.5) applications deployed on newer servers. I assume that your apps have a common domain and thus are able to share cookies.

Back in MVC4 times, you probably were using forms authentication and membership roles to authorize users trying to call actions on the controllers. ASP.NET MVC5 still supports this way of securing web applications so we could achieve our goal by enabling forms/membership settings in web.config. I’m not a big fan of this solution as it won’t allow us to use more secure and feature-rich security model introduced in a new version of the framework. What I’m proposing is to use ASP.NET Identity with the Owin security pipeline in new applications and slightly modified forms authentication in older apps. Authorization should be based on claims. Our sample solution will include two applications:

  1. IdentityAuth – the MVC5 application and
  2. MembershipAuth – a legacy .NET4.0 application

ASP.NET Identity Application (IdentityAuth)

It’s a slightly modified template of the default ASP.NET MVC5 application. We will enable CookieAuthenticationMiddleware to persist user authentication data between requests:

namespace IdentityAuth
    public partial class Startup
        // For more information on configuring authentication, 
        // please visit
        public void ConfigureAuth(IAppBuilder app)
            // Enable the application to use a cookie to store information for the signed in user
            app.UseCookieAuthentication(new CookieAuthenticationOptions
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login"),
                CookieSecure = CookieSecureOption.Never,
                Provider = new CookieAuthenticationProvider { }

AccountController has only Login, Index and Logout actions defined. The Login action accepts only two accounts: test and admin (normally, you would use an instance of the UserManager class to validate user accounts). Additionally, test account has a special usertype claim added, which we will use in the authorization logic:

public ActionResult Login(LoginModel model)
    if (!String.Equals(model.Login, "test", StringComparison.Ordinal) 
    && !String.Equals(model.Login, "admin", StringComparison.Ordinal) ||
        !String.Equals(model.Password, "1234", StringComparison.Ordinal)) {
        return new HttpStatusCodeResult(HttpStatusCode.Unauthorized);

    var identity = new GenericIdentity(model.Login, "ApplicationCookie");
    var claims = new Claim[0];
    if (model.Login.Equals("test", StringComparison.Ordinal))
        claims = new[] { new Claim("urn:usertype", "king") };
    var claimsIdentity = new ClaimsIdentity(identity, claims);

    AuthenticationManager.SignIn(new AuthenticationProperties() { }, claimsIdentity);

    return RedirectToAction("Index");

Next to the usual AuthenticationManager.SignIn (which authenticates user in Owin-based apps), we also call SetFormsAuthCookie. This is a method which will set a forms cookie compatible with our legacy application:

private void SetFormsAuthCookie(ClaimsIdentity identity) {
    // we need to serialize claims to string
    var userData = JsonConvert.SerializeObject(identity.Claims.Select
    (c => new SimpleClaim { ClaimType = c.Type, Value = c.Value }));
    // then create an auth ticket
    var cookie = FormsAuthentication.GetAuthCookie(identity.Name, false);
    var authTicket = FormsAuthentication.Decrypt(cookie.Value);
    authTicket = new FormsAuthenticationTicket(authTicket.Version, authTicket.Name,
                                               authTicket.IssueDate, authTicket.Expiration,
    cookie.Value = FormsAuthentication.Encrypt(authTicket);
    // and place it in authorization cookie


public class SimpleClaim
    public String ClaimType { get; set; }

    public String Value { get; set; }

Notice that in the user data section of the authentication ticket, we store serialized user claims. Logout action is really simple:

public ActionResult Logout()

    return RedirectToAction("Login");

Last part of the IdentityAuth application that requires some explanation is the configuration file, especially system.web section:

  <machineKey compatibilityMode="Framework20SP2"
  validation="HMACSHA256" decryption="AES" />
  <compilation debug="true" targetFramework="4.5"/>
  <httpRuntime targetFramework="4.5"/>
  <customErrors mode="Off" />

  <authentication mode="None">
    <forms loginUrl="~/Account/Login" name="testauth"
    timeout="2880" ticketCompatibilityMode="Framework40"
    enableCrossAppRedirects="false" />

We set the authentication mode to None as we are using the Owin authentication middleware, but at the same time we configure forms authentication – these settings must be the same as in our legacy application. Notice also that machineKey has the compatibilityMode set to Framework20SP2.

Forms/Membership Application (MembershipAuth)

Let’s now focus on the .NET4.0 application which needs to understand the authentication context we’ve just configured. We will start from examining system.web section of the web.config file:

  <machineKey compatibilityMode="Framework20SP2"
  validation="HMACSHA256" decryption="AES" />
  <httpRuntime />
  <compilation debug="true" targetFramework="4.0" />
  <authentication mode="Forms">
    <forms loginUrl="~/Account/Login" timeout="2880"
    name="testauth" enableCrossAppRedirects="false" />
  <validation validateIntegratedModeConfiguration="false" />
    <add name="ClaimsFormsAuthentication"
    type="MembershipAuth.HttpModules.ClaimsFormsAuthenticationModule" />

Notice that the machineKey and forms sections are exactly the same as in the IdentityAuth application. Additionally, we have authentication mode set to Forms. In order to use claims identity, we need to implement a custom ClaimsFormsAuthenticationModule:

namespace MembershipAuth.HttpModules
    public class ClaimsFormsAuthenticationModule : IHttpModule
        public void Dispose()

        public void Init(HttpApplication context)
            context.PostAuthenticateRequest += context_PostAuthenticateRequest;

        void context_PostAuthenticateRequest(object sender, EventArgs e)
            var user = HttpContext.Current.User;
            if (user != null && user.Identity.IsAuthenticated && user.Identity is FormsIdentity)
                var formsIdentity = (FormsIdentity)user.Identity;
                // user is authenticated - we will transform his identity
                var claimsPrincipal = new ClaimsPrincipal(user);
                var claimsIdentity = (ClaimsIdentity)claimsPrincipal.Identity;

                if (!String.IsNullOrEmpty(formsIdentity.Ticket.UserData))
                    foreach (var sc in JsonConvert.DeserializeObject<IEnumerable<SimpleClaim>>
                        var c = new Claim(sc.ClaimType, sc.Value);
                        if (!claimsIdentity.Claims.Contains(c))

                HttpContext.Current.User = claimsPrincipal;
                Thread.CurrentPrincipal = claimsPrincipal;

        public class SimpleClaim
            public String ClaimType { get; set; }

            public String Value { get; set; }

As you can see, after successful forms authentication, we transform the FormsIndentity into ClaimsIdentity. Additionally, we deserialize user data of the forms authentication ticket into claims. I haven’t mentioned yet how I imported claims classes and structures into a .NET4.0 application. I needed to install a Windows Identity Foundation (aka Microsoft.IdentityModel) Nuget package which is a predecessor of the System.IdentityModel assembly. I also added the following lines to the web.config file:

  <section name="microsoft.identityModel"
  type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection, Microsoft.IdentityModel,
  Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    <claimsAuthorizationManager type="MembershipAuth.Authz.AuthorizationManager" />

Our claims authorization manager is quite simple and it only checks if user is trying to perform LoginAsKing action is actually a king:

namespace MembershipAuth.Authz
    public class AuthorizationManager : ClaimsAuthorizationManager
        public override bool CheckAccess(AuthorizationContext context)
            var action = context.Action.FirstOrDefault();
            if (action != null && String.Equals
                (action.Value, "LoginAsKing", StringComparison.Ordinal)) {
                foreach (ClaimsIdentity identity in context.Principal.Identities) {
                    if (identity.Claims.Where(c => String.Equals
                       (c.ClaimType, "urn:usertype", StringComparison.Ordinal)
                       && String.Equals(c.Value, "king", StringComparison.Ordinal)).Any()) {
                        return true;
            return false;

Finally, it’s time to bind our AuthorizationManager with actions in the controller. For this purpose, we will use the Thinktecture.IdentityModel library (available as a Nuget package for .NET4.0 and .NET4.5). It implements a ClaimsAuthorizeAttribute which you can use to apply resource/action based authorization in your application. It’s a much better choice than the framework’s default role based authorization which forces you to mix business and authorization logic (more on this subject can be found in Dominick Baier’s article: Finally it’s time to present our HomeController actions:

namespace MembershipAuth.Controllers
    public class HomeController : Controller
        // GET: /Home/

        public ActionResult Index() {
            return Content(User.Identity.IsAuthenticated ? User.Identity.Name : "Anonymous");

        public ActionResult Auth() {
            return Content("auth");

        public ActionResult ClaimsAuth()
            return Content("authz");

Only test user will be allowed to perform ClaimsAuth action as only he claims to be a king :). Both admin and test can call Auth action. As you can see, our MembershipAuth application understands cookies generated by the IdentityAuth application and additionally authorizes users based on theirs claims – our goal is achieved.

I strongly encourage you to use Thinktecture.IdentityModel library to implement action/resource based authorization in all your applications. Also, if you need to migrate data model from SQL Membership to ASP.NET Identity, check out this tutorial. Finally, the source code of the MembershipAuth and the IdentityAuth applications is available for download from my blog samples site.

Filed under: ASP.NET Security, CodeProject 


This article, along with any associated source code and files, is licensed under The MIT License


About the Author

Sebastian Solnica
Software Developer (Senior)
Poland Poland
Interested in tracing, debugging and performance tuning of the .NET applications.

My twitter: @lowleveldesign
My website:

You may also be interested in...

Comments and Discussions

-- There are no messages in this forum --
Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web01 | 2.8.190518.1 | Last Updated 7 Aug 2014
Article Copyright 2014 by Sebastian Solnica
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid