Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding Claims-based authorization to MVC 3

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

like image 637
chief7 Avatar asked May 13 '11 21:05

chief7


People also ask

How would you implement claims based authentication in .NET core?

The claims-based authorization works by checking if the user has a claim to access an URL. In ASP.NET Core we create policies to implement the Claims-Based Authorization. The policy defines what claims that user must process to satisfy the policy. We apply the policy on the Controller, action method, razor page, etc.

What is an advantage of using a policy based authorization instead of a role based one?

By using Policy-based & Role-based Authorization process, we can provide access to particular area of application to the user based on the Role/Policy of the user.

What is claims MVC?

Claim based authorization checks are declarative - the developer embeds them within their code, against a controller or an action within a controller, specifying claims which the current user must possess, and optionally the value the claim must hold to access the requested resource.


2 Answers

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.

like image 56
Eugenio Pace Avatar answered Sep 27 '22 23:09

Eugenio Pace


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).

like image 25
rbrayb Avatar answered Sep 28 '22 01:09

rbrayb