user3788671
user3788671

Reputation: 2047

Applying custom security method to all actions

I have a method that returns a bool, true being the user is allowed to access the site and false being the user has not access to the site. As of right now I have a separate action that is called in each Action and if the user if the method returns false the user is directed to a view that says "access denied". I was wondering there is a better way to do this without throwing the duplicate code in each individual action any maybe replace it with one single call because the user will either be able to access all of the pages or non of the page.

Here is an example of what I have:

    [HttpGet]
    public ActionResult EmployeeAdd()
    {
        if (!GetUsersecurityLevel())
        {
            return RedirectToAction("NotAuthorizedForApplication");
        }

        ...........

        return View();
    }

    [HttpGet]
    public ActionResult EmployeeEdit()
    {
        if (!GetUsersecurityLevel())
        {
            return RedirectToAction("NotAuthorizedForApplication");
        }

        ..........

        return View();
    }

    [HttpGet]
    public ActionResult EmployeeDelete()
    {
        if (!GetUsersecurityLevel())
        {
            return RedirectToAction("NotAuthorizedForApplication");
        }

        ..........

        return View();
    }


    public string CurrentUserName()
    {
        return User.Identity.Name.Substring(User.Identity.Name.IndexOf(@"\", StringComparison.Ordinal) + 1).ToUpper();
    }

Web.Config:

  <system.web>
    <authentication mode="Windows" />
    <authorization><deny users="?"/></authorization>
    <compilation debug="true" targetFramework="4.0"/>
    <httpRuntime targetFramework="4.0"/>
    <customErrors mode="Off" />
  </system.web>

So my questions is: Can I make one single call on the GetUserSecurityLevel() which can protect all of the actions from being ran by unauthorized users?

Upvotes: 0

Views: 77

Answers (3)

ataravati
ataravati

Reputation: 9155

Create a custom authorize attribute like this:

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var username = httpContext.User.Identity.Name;
        return GetUserSecurityLevel(username);
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {            
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        if (!AuthorizeCore(filterContext.HttpContext))
        {
             // If not authorized, redirect to the NotAuthorizedForApplication action 
             filterContext.Result = new RedirectToRouteResult(
                new System.Web.Routing.RouteValueDictionary {
                   {"action", "NotAuthorizedForApplication"}
                }
             );               
        }
    }

    private bool GetUserSecurityLevel(string username)
    {
        // Your code to authorize users...
    }
}

Then, you can use it in your controller or actions like this:

[HttpGet]
[MyAuthorize]
public ActionResult EmployeeAdd()
{
    ...........

    return View();
}

However, if there's only one level of access, why don't you use NT groups (roles) for authorization?

UPDATE:

Make sure Windows Authentication is enabled on IIS, and in your web.config file, inside <system.web> you have:

<authentication mode="Windows" />
<authorization>
  <deny users="?" />
</authorization>

Upvotes: 3

Dan Hunex
Dan Hunex

Reputation: 5318

The following might help you. Once you override the AuthorizeCore , then you can use it in your controller and it will apply to all of your actions. You can also apply it to each action method independently

 public class AdminAuthorizeAttribute: AuthorizeAttribute
     {

      protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
          {
              return !base.AuthorizeCore(httpContext)? false:GetUsersecurityLevel();
          }
     }

then on the controller

you can do

at Controller level

 [AdminAuthorize]
 public class YourController:Controller 
       {

       }

Or action level

 [HttpGet]
 [AdminAuthorize]
 public ActionResult EmployeeAdd()

Upvotes: 1

iaq
iaq

Reputation: 215

Custom authorisation filter is the best solution as suggested by ataravati.

Upvotes: 0

Related Questions