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
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.
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.
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.
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With