Authorization vs. Authentication
Where authentication answers 'who are you?', authorization answers 'what are you allowed to do?' -- and in ASP.NET MVC this decision is made after the ClaimsPrincipal is already attached to HttpContext.User, typically by an AuthorizeAttribute evaluated during the AuthorizationFilters stage of the MVC pipeline, well before model binding or the action method body runs. If the check fails, the filter short-circuits execution and returns a 401 or redirects to the login page, meaning the controller action's code never executes at all for an unauthorized caller.
Cricket analogy: It's like a stadium already confirming your ticket got you through the gate (authentication), but a separate steward checking whether that ticket permits access to the members' pavilion versus general stands (authorization).
The [Authorize] Attribute and Role Checks
Decorating a controller or action with [Authorize] requires any authenticated user, while [Authorize(Roles = "Admin,Manager")] additionally requires membership in at least one listed role, evaluated against the roles present in the current ClaimsPrincipal (typically populated from ClaimTypes.Role claims by RoleManager<IdentityRole> during sign-in). Because role checks are OR-based across a comma-separated list but AND-based when stacking multiple [Authorize] attributes on the same action, a developer must be careful: [Authorize(Roles="Admin")] followed by [Authorize(Roles="Manager")] on the same method actually requires both roles simultaneously, not either.
Cricket analogy: It's like the ICC granting match-referee status to anyone with a valid accreditation, but reserving the toss-supervision duty specifically for umpires with the 'Elite Panel' or 'International Panel' designation.
Custom Authorization Filters and Resource-Based Checks
Role checks alone can't express rules like 'a user may only edit their own order,' so ASP.NET MVC lets you write a custom AuthorizeAttribute by overriding AuthorizeCore(HttpContextBase httpContext), or better, perform resource-based authorization inside the action itself by comparing the resource's owner ID against User.Identity.GetUserId(). For cross-cutting policies -- like requiring a verified email before checkout -- teams often implement a custom filter that inspects claims (e.g., a custom EmailVerified claim) rather than overloading the Roles property, keeping role membership and fine-grained business rules as separate concerns.
Cricket analogy: It's like a franchise rule that a player can only request a review (DRS) on a decision affecting their own dismissal, not any teammate's -- a resource-ownership check beyond simple team membership.
// Role-based authorization on a controller
[Authorize(Roles = "Admin,Manager")]
public class ReportsController : Controller
{
public ActionResult Index() => View();
// Stacking attributes = AND, not OR
[Authorize(Roles = "Admin")]
public ActionResult DeleteAll() => View();
}
// Resource-based authorization inside an action
[Authorize]
public ActionResult Edit(int id)
{
var order = _db.Orders.Find(id);
if (order == null) return HttpNotFound();
var currentUserId = User.Identity.GetUserId();
if (order.OwnerUserId != currentUserId && !User.IsInRole("Admin"))
{
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
}
return View(order);
}
// Custom claims-based authorize attribute
public class RequireEmailVerifiedAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var identity = httpContext.User.Identity as ClaimsIdentity;
return identity != null &&
identity.HasClaim(c => c.Type == "EmailVerified" && c.Value == "true");
}
}[Authorize] with no parameters only checks that the user is authenticated -- it grants access to any logged-in user regardless of role. Always be explicit with Roles or a custom policy when an action should be restricted beyond 'just logged in.'
Never rely solely on hiding a link or menu item in the view to 'protect' an action. If the controller action itself isn't decorated with [Authorize], any authenticated (or even anonymous) user can invoke it directly by URL, bypassing the UI entirely.
- Authorization decides what an already-authenticated user is allowed to do, evaluated by filters before the action executes.
- [Authorize] alone requires any authenticated user; [Authorize(Roles="A,B")] requires membership in at least one listed role.
- Stacking multiple [Authorize] attributes on one action is an AND, not an OR, of their conditions.
- Resource-based rules like 'edit only your own record' require checks inside the action or a custom AuthorizeAttribute.
- Custom AuthorizeAttribute subclasses override AuthorizeCore to inspect claims beyond simple role membership.
- Hiding UI elements is not a substitute for decorating the underlying controller action with proper authorization.
- Unauthorized requests are short-circuited by the filter pipeline, so the action method body never runs.
Practice what you learned
1. What does a bare [Authorize] attribute with no Roles parameter actually enforce?
2. If a controller has [Authorize(Roles="Admin")] on the class and a second [Authorize(Roles="Manager")] on a specific action, what is required to call that action?
3. Which method do you override to implement a custom claims-based AuthorizeAttribute?
4. Why can't [Authorize(Roles="...")] alone express a rule like 'users may only edit their own order'?
5. Where in the MVC pipeline does an [Authorize] failure short-circuit request processing?
Was this page helpful?
You May Also Like
Authentication in MVC
How ASP.NET MVC applications verify user identity using Forms Authentication, ASP.NET Identity, OWIN middleware, and external login providers.
Securing MVC Applications
A practical checklist of ASP.NET MVC security concerns beyond authentication -- output encoding, HTTPS enforcement, secure headers, and safe error handling.
Anti-Forgery Tokens
How ASP.NET MVC prevents Cross-Site Request Forgery (CSRF) using the @Html.AntiForgeryToken helper and the ValidateAntiForgeryToken filter.
Related Reading
Related Study Notes in Microsoft Technologies
Browse all study notesWindows 10 / UWP Development Study Notes
.NET · 30 topics
Microsoft TechnologiesWindows Batch Scripting Study Notes
Batch · 30 topics
Microsoft TechnologiesMFC (Microsoft Foundation Classes) Study Notes
C++ · 30 topics
Microsoft TechnologiesSilverlight Study Notes
.NET · 30 topics
Microsoft TechnologiesXAML Study Notes
.NET · 30 topics
Microsoft TechnologiesWPF (Windows Presentation Foundation) Study Notes
.NET · 30 topics