Reputation: 5801
I have my Action Method
[Authorize(Roles="Admin")]
public ActionResult EditPosts(int id)
{
return View();
}
In my case I need to authorize administrators so they can edit posts but (here comes the cool part), I also need to allow the creator of the post to be able to edit the post which is a normal user. So how can I filter out the user that created the post as well as the admins but leave the others unauthorized? I am receiving the PostEntry id as a route parameter but that's after the attribute and also attributes only accept constant parameters, looks like something very difficult, your answers are highly appreciated, Cheers!
Upvotes: 35
Views: 58359
Reputation: 1292
I understand that you have already accepted an answer, and this was posted a while back.. (btw:excellent answer for adding custom attributes), However I would point out the following:
If you are using this attribute once. On a Single method. This isn't a good implementation. Instead you should have:
[Authorize] // Just make sure they are auth'ed at all.
public ActionResult EditPosts(int id)
{
Post SomePost = findPostByID (id); // However you do it - single lookup of post
if (!user.IsInRole("Admin") && !{IsOwnerOfPost(post)} ) Return Not Authorized
... Edit post code here
}
This has the advantages of:
Upvotes: 9
Reputation: 1038820
You could write a custom authorize attribute:
public class AuthorizeAdminOrOwnerOfPostAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
// The user is not authenticated
return false;
}
var user = httpContext.User;
if (user.IsInRole("Admin"))
{
// Administrator => let him in
return true;
}
var rd = httpContext.Request.RequestContext.RouteData;
var id = rd.Values["id"] as string;
if (string.IsNullOrEmpty(id))
{
// No id was specified => we do not allow access
return false;
}
return IsOwnerOfPost(user.Identity.Name, id);
}
private bool IsOwnerOfPost(string username, string postId)
{
// TODO: you know what to do here
throw new NotImplementedException();
}
}
and then decorate your controller action with it:
[AuthorizeAdminOrOwnerOfPost]
public ActionResult EditPosts(int id)
{
return View();
}
Upvotes: 74