I've seen that the AuthoriseAttribute can work for each individual controller, what i would like to do is set the entire site permissions to one AD group, is that easy to do or should i just copy and paste the authattrib line to each controller?
Thanks
As #asawyer mentioned using global filter for your case is good practise. For another part of your question in comment: in the global filter where do i specify what AD groups are allowed to use the site? you can specify roles in OnAuthorization method of your custom authorize attribute, smth like:
public class MyAuthAttribute: AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
Roles = 'ad role1, ad role2...'; //Roles is AuthorizeAttribute member
base.OnAuthorization(filterContext);
}
}
and than use it like:
GlobalFilterCollection.Add(new MyAuthAttribute());
in global.asax or w/e else
Related
I understand different types of filters are available in ASP.NET MVC. Now I am confused about the following 3 types of filters. I have to use custom filters in my code.
Authentication Filter
Authorization Filter
Action Filter
I have users, roles and their permissions (read, add, delete) in 4 different tables.
Which filter method I should choose?
When I did a search, I am able to found some of them using Action filters as
public class MyFirstCustomFilter : ActionFilterAttribute
{
....
}
OnActionExecuting - my code goes here for role and permmsion - is this correct way ?
OnResultExecuting
But some article use
public class CustomAuthAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
//my code goes here for role and permission check - is this correct way ?
}
}
I want to check user is eligible to execute particular action based on roles & permission in db.
Now I am confused with all these methods. For me, all are similar. Correct me if I am wrong.
I have a project layout like:
Areas | Admin
Areas | FrontEnd
I want to [Authorize] users per area (as Admin will use a different table to users in FrontEnd. When I use the [Authorize] tag in a Controller in my Admin area, it redirects me to the forms authentication login url which is set in the root web.config file.
Is it possible to override this per area? I see each area has a Web.config file but it seems to ignore the forms authentication setting if I add it in there.
If I am approaching this in the wrong way, I am happy to take some advice.
Edit:
I have tried something but don't know if it's best practice. Basically, implement my own CustomAuth attribute and redirect:
public class CustomAuth : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (!base.AuthorizeCore(httpContext))
httpContext.Response.Redirect("~/Admin/Account");
return true;
}
}
Is this a valid approach?
I ended up going with my own [Authorise] attribute and redirecting on Unauthorised access.
public class AuthorizeArea : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new RedirectResult("/Admin/Account");
}
}
I started off using the default project's AccountController, but I've extended/changed it beyond recognition. However, in common with the original I have a LogOn and LogOff action.
Clearly, the LogOn action must be accessible to everyone. However, since I've added lots of other actions to this controller (to create & edit users), I want 99% of the actions to require administrator role membership.
I could decorate all my actions with [Authorize Roles="Administrators"] but there's a risk I'll forget one. I'd rather make it secure by default, by decorating the controller class itself with that attribute, and then relax the requirement on my LogOn method. Can I do that?
(As in, can I do that out-of-the-box without creating custom classes, etc. I don't want to complicate things more than necessary.)
To override an controller Attribute at the Action level you have to create a custom Attribute and then set the Order property of your custom attribute to a higher value than the controller AuthorizeAttribute. I believe both attributes are then still executed unless your custom attribute generates a result with immediate effect such as redirecting.
See Overriding controller AuthorizeAttribute for just one action for more information.
So I believe in your case you will just have to add the AuthorizeAttribute on the Actions and not at the controller level. You could however create a unit test to ensure that all Actions (apart from LogOn) have an AuthorizeAttribute
You can use AuthorizeAttribute on your class
http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.aspx
For relaxing you can implement for example a custom action filter attribute like this (I didn' test if it works).
public class GetRidOfAutorizationAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
// you can for example do nothing
filterContext.Result = new EmptyResult();
}
}
After way too much time, I came up with a solution.
public class OverridableAuthorize : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
var action = filterContext.ActionDescriptor;
if(action.IsDefined(typeof(IgnoreAuthorization), true)) return;
var controller = action.ControllerDescriptor;
if(controller.IsDefined(typeof(IgnoreAuthorization), true)) return;
base.OnAuthorization(filterContext);
}
}
Which can be paired with IgnoreAuthorization on an Action
public class IgnoreAuthorization : Attribute
{
}
I'm trying to implement a custom RoleProvider in my ASP.NET MVC application.
I've created a custom MembershipProvider and it works, in that I'm able to successfully validate the user. The next step is to implement the RoleProvider to restrict access to certian Controllers to Admin users only.
Can anyone provide me with a quick outline of the steps I need to take?
The point that I'm at now is I have my controller with the Authorize filter, like so:
[Authorize(Roles="Admin")]
public class AdminOnlyController : Controller
{
// stuff
}
and I have my CustomRoleProvider class, with the following method along with a load of not-implemented Methods:
public override string[] GetRolesForUser(string username)
{
if (username == "dave")
{
return new string[] { "Admin" };
}
}
I think I need to add the user to the Role somehow but I don't know how to do that. Ideally the end result would be a scenario where unauthorized users can't access certain controllers, and I in my Views I could determine whether to show links with something like:
if (User.IsInRole("Admin"))
{
// show links to Admin Controllers
}
Can anyone point me in the right direction?
I used this as as base line for a custom role manager: http://davidhayden.com/blog/dave/archive/2007/10/17/CreateCustomRoleProviderASPNETRolePermissionsSecurity.aspx
Should work in MVC or Web Forms.
UPDATE: Since that web page no longer exists, you could try this one instead. The basic requirements are that you need to implement the RoleProvider interface, namely:
void AddUsersToRoles(string[] usernames, string[] roleNames)
string[] GetRolesForUser(string id)
bool RoleExists(string roleName)
For the not-implemented methods, be sure to throw a NotImplementedException. This should help you figure out which methods are needed in your custom provider to get the job done.
I suspect you'll have to implement IsUserInRole.
I realise that I can prevent unauthenticated users from accessing views at controller level by applying the [Authorize] attribute and can also filter views down to individual users or roles using this. However, my question is regarding doing the opposite... Is there a way to deny authenticated users from certain views without having to manually add in checks to see if they're authenticated in the opening lines of the controller code? Ideally an [Unauthorized] attribute or an equivalent if such a thing exists?
The reason for this is that I don't want authenticated users to be able to visit the account creation pages of the site I'm working on, as well as other resources. I realise I could check them in the controller explicitly but I'd prefer to decorate the controller methods if at all possible.
Thanks :)
This is along the lines of what LukLed was referring to:
public class UnAuthorizedAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
bool excludeCondition = false;
if (excludeCondition)
filterContext.Result = new HttpUnauthorizedResult();
else
base.OnAuthorization(filterContext);
}
}
Simply put in the logic for your excludeCondition. You can also to choose to do things like redirect to other views. Just mark your code with [UnAuthorized]
You can write your own authorization filter. Inherit from FilterAttribute and implement IAuthorizationFilter. Call it UnauthorizedAttibute and you will be able to use it like [Authorize].
Hear You can read about filters:
http://www.asp.net/LEARN/mvc/tutorial-14-cs.aspx
A simple way to accomplish this? Just leave the action untagged, and start with:
If(Request.IsAuthenticated)
// redirect somewhere, or return another view...
this could also be accomplished fairly simply if you are already using a roleprovider. then your actions would just need to be filtered by the appropriate role:
[Authorize(Roles = "Admin, Editor")]