Search code examples
c#asp.net-mvc-3exceptionfluent-security

Catch exceptions from RequiredRole and other policies to redirect using Fluent Security


Using Fluent Security, I have configured website access using DenyAnonymousAccess, DenyAuthenticationAccess and RequireRole.

SecurityConfigurator.Configure(configuration =>
{
    configuration.ResolveServicesUsing(new FluentSecurityServiceLocator());
    configuration.GetAuthenticationStatusFrom(CurrentUser.IsAuthenticated);

    configuration.GetRolesFrom(CurrentUser.Roles);

    configuration.For<HomeController>().DenyAnonymousAccess();
    configuration.For<ReportsController>().RequireRole(UserRole.Administrator);
    configuration.For<AccountController>().DenyAuthenticatedAccess();

    configuration.For<AccountController>(x => x.ChangePassword()).DenyAnonymousAccess();
});

I've handled the PolictyViolationException for DenyAnonymousAccess and redirected to the logon page.

public ActionResult Handle(PolicyViolationException exception)
{
    return new RedirectToRouteResult(
       new RouteValueDictionary(new { action = "Login", controller = "Account" })
       );
}

But I'm not sure if catching an exception from RequireRole is the same process? I need to redirect if RequireRole is violated.

Also, when user isn't logged on and clicks a link attached to a role, I get the unhandled version of denyanonymousaccess exception. What am I doing wrong in my configuration and implementation??


Solution

  • You have to define the name of the violation handler class correctly. It depends on the violation which needs to be handled. If you are handling the violation for DenyAnonymousAccessPolicy, your violation handler class must have the name start with the policy name and it must implement IPolicyViolationHandler. This rule must be followed for all policy violations like this:

    public class DenyAnonymousAccessPolicyViolationHandler : IPolicyViolationHandler
    {
        public ActionResult Handle(PolicyViolationException exception)
        {
    
            //Log the violation, send mail etc. etc.
            var rvd = new RouteValueDictionary(new
            {
                area = "",
                controller = "Account",
                action = "LogOn",
                statusDescription = exception.Message
            });
            return new RedirectToRouteResult(rvd);
    
        }
    }
    

    For RequireRolePolicy, the handler should look like this:

    public class RequireRolePolicyViolationHandler : IPolicyViolationHandler
    {
        public ActionResult Handle(PolicyViolationException exception)
        {
    
            //Log the violation, send mail etc. etc.
            var rvd = new RouteValueDictionary(new
            {
                area = "",
                controller = "Home",
                action = "Home",
                statusDescription = exception.Message
            });
            return new RedirectToRouteResult(rvd);
    
        }
    }
    

    Check this link for further knowledge on fluent security policy violation handlers.

    https://github.com/kristofferahl/FluentSecurity/wiki/Policy-violation-handlers-2.0

    Hope it helps!!!