3

In my database, the system user has a list of modules he/she can access.

I would like to be able to add an authorise attribute which checks that this is the case.

E.g. [authorise(UserID, ControllerName)]

Which goes to some code, ensures that the User with UserID specified, has the controller name in his/her list.

At the moment you can simply bypass the fact the tabs aren't visible, by using the URL. (I have code which already checks if the user has specified access and hides/shows tabs)

3 Answers 3

7
public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var isAuthorized = base.AuthorizeCore(httpContext);
        if (!isAuthorized)
        {
            return false;
        }

        string currentUser = httpContext.User.Identity.Name;
        string currentController = httpContext.Request.RequestContext.RouteData.GetRequiredString("controller");

        // TODO: go hit your database and see if currentUser can access
        // currentController and return true/false from here

        ...
    }
}

then decorate your controllers or actions:

[MyAuthorize]
public class FooController: Controller
{
    ...
}

This being said I suspect that you might have gone the wrong way in your database design by storing a list of which user has access to access which controller action. Probably you should have used roles for that. Having the database know about controllers just feels wrong.

So:

[Authorize(Roles = "Foo,Bar")]
public class FooController: Controller
{
    ...
}

Only users that have the Foo or Bar role can access the FooController.

Sign up to request clarification or add additional context in comments.

3 Comments

If you want to pass the values in yourself, then just add the properties UserID and ControllerName to Darin's class. Then access your [MyAuthorize(UserID = xx, ControllerName = "xxx")].
Any way to redirect them to Home/index? Apart from that, works great. thanks! The names of the controllers arent in the database, but a corrosponding module key is. Its a webfront for an existing app/database, so am forced to use the current structure.
@Doomsknight, sure, just change the login url in your web.config. Or if you want more fine grained control over what does the attribute do if it authentication fails you could override the HandleUnauthorizedRequest method.
1

You can create a new attribute.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class CustomAuthorizeAttribute : FilterAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new HttpUnauthorizedResult();
        }


        bool authorized = // Perform custom logic

        If(!authorized)
        {
            filterContext.Result = new RedirectResult(/* Your access denied url */);
        }
    }

}

Comments

0

When you create the model, check the permission

DisplayAdminLink = _permissionService.Authorize(StandardPermissionProvider.AccessAdminPanel),

and in the view

    @if (Model.DisplayAdminLink)
    {
        <li><a href="@Url.Content("~/admin")" class="ico-admin">@T("Account.Administration")</a>
        </li>
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.