saber saber - 1 month ago 14
ASP.NET (C#) Question

How to redirect to specific page in FluentSecurity?

Hi I'm using FluentSecurity to authenticate and verify users permissions in my MVC application. In the basic settings when a user wants to access to denied

Action
it throws an exception. I want to know how should I redirect to another page (such as login page) instead of showing yellow exception page ?

Answer

I know this question has been answered already but I don't like putting a try catch in every action to handle this situation.

Fluent Security allows you to register a handler for policy violations (see https://github.com/kristofferahl/FluentSecurity/wiki/Policy-violation-handlers). You have to have a class that inherits from IPolicyViolationHandler. The convention is to name your class <PolicyViolationName>PolicyViolationHandler

Here is an example of a Handler to register a DenyAnonymousAccessPolicyViolationHandler

    /// <summary>
    /// Custom Policy Violation Handler. See http://www.fluentsecurity.net/wiki/Policy-violation-handlers
    /// </summary>
    public class DenyAnonymousAccessPolicyViolationHandler : IPolicyViolationHandler
    {
        public ActionResult Handle(PolicyViolationException exception)
        {
            Flash.Error("You must first login to access that page");
            return new RedirectResult("/");
        }
    }

One other caveat that you will run into is that you have to use an IOC container to register these handlers. I won't debate whether using and IOC container is good or bad but I prefer not to use on if I don't have too. On their website there was a blog written on how to do this without using an IOC container but I didn't really like that approach as well. Here is what I did.

public static class SecurityConfig
    {
        public static void Configure()
        {
            SecurityConfigurator.Configure(c =>
                {
                    c.GetAuthenticationStatusFrom(() => HttpContext.Current.User.Identity.IsAuthenticated);
                    c.GetRolesFrom(() => (HttpContext.Current.Session["Roles"] as string[]));
                        // Blanked Deny All
                    c.ForAllControllers().DenyAnonymousAccess();

                    // Publicly Accessible Areas
                    c.For<LoginController>().Ignore();

                    // This is the part for finding all of the classes that inherit
                    // from IPolicyViolationHandler so you don't have to use an IOC
                    // Container.
                    c.ResolveServicesUsing(type =>
                        {
                            if (type == typeof (IPolicyViolationHandler))
                            {
                                var types = Assembly
                                    .GetAssembly(typeof(MvcApplication))
                                    .GetTypes()
                                    .Where(x => typeof(IPolicyViolationHandler).IsAssignableFrom(x)).ToList();

                                var handlers = types.Select(t => Activator.CreateInstance(t) as IPolicyViolationHandler).ToList();

                                return handlers;
                            }
                            return Enumerable.Empty<object>();
                        });
                });
        }
    }
Comments