Adding Claims-based authorization to MVC 3

10,178

Solution 1

You can use WIF in MVC without an STS.

I used the default MVC2 template, but it should work with MVC 3 too.

You need to:

1- Plug WIF 's SessionAuthenticationModule (web.config)

< add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

2- Wherever you authenticate your users, create a ClaimsPrincipal, add all required claims and then create a SessionSecurityToken. This is the LogOn Action in the AccountController created by MVC:

 [HttpPost]
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (MembershipService.ValidateUser(model.UserName, model.Password))
                {
                    var cp = new ClaimsPrincipal();
                    cp.Identities.Add(new ClaimsIdentity());
                    IClaimsIdentity ci = (cp.Identity as IClaimsIdentity);

                    ci.Claims.Add(new Claim(ClaimTypes.Name, model.UserName));

                    SessionSecurityToken sst = FederatedAuthentication
                        .SessionAuthenticationModule
                        .CreateSessionSecurityToken(cp,
                                                    "MVC Test",
                                                    DateTime.
                                                        UtcNow,
                                                    DateTime.
                                                        UtcNow.
                                                        AddHours
                                                        (1),
                                                    true);


                    FederatedAuthentication.SessionAuthenticationModule.CookieHandler.RequireSsl = false;
                    FederatedAuthentication.SessionAuthenticationModule.AuthenticateSessionSecurityToken(sst, true);


                    //FormsService.SignIn(model.UserName, model.RememberMe);
                    if (!String.IsNullOrEmpty(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        return RedirectToAction("Index", "Home");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "The user name or password provided is incorrect.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

I just added the required lines and left everything else the same. So some refactoring might be required.

From there on, your app will now receive a ClaimsPrincipal. All automatically handled by WIF.

The CookieHandler.RequiresSsl = false is only because it's a dev machine and I'm not deploying on IIS. It can be defined in configuration too.

Solution 2

WIF is designed to use a STS so if you don't want to do that, then you essentially have to re-invent the wheel as per the article.

When you move to ADFS, you will pretty much have to re-code everything.

Alternatively, have a look at StarterSTS, This implements the same kind of aspnetdb authentication that you need but allows WIF to do the heavy lifting. Then when you migrate to ADFS, you simply have to run FedUtil against ADFS and it will all work without any major coding changes.

(BTW, there is a MVC version - a later implementation - here).

Share:
10,178
chief7
Author by

chief7

Solution Architect at a large private enterprise where we build key internal business systems.

Updated on June 06, 2022

Comments

  • chief7
    chief7 almost 2 years

    I have an MVC app that I would like to add claims-based authorization to. In the near future we will use ADFS2 for federated identity but for now we will used forms auth locally.

    Has anyone seen a tutorial or blog post about the best way to use WIF without an external identity provider?

    I have seen the following but it is a year old now and I think there should be an easier solution:

    http://geekswithblogs.net/shahed/archive/2010/02/05/137795.aspx

  • BentOnCoding
    BentOnCoding over 11 years
    So how would you go about adding another identity provider ? like google or adfs ?