Marek Woźniak
Marek Woźniak

Reputation: 1786

info for page if requiment roles

i have a controller which requirement a role names "Admin":

it's part of controller:

[Authorize(Roles="Admin")]
public class RolesAdminController : Controller
{
    public RolesAdminController()
    {
    }

    public RolesAdminController(ApplicationUserManager userManager,
        ApplicationRoleManager roleManager)
    {
        UserManager = userManager;
        RoleManager = roleManager;
    }

    private ApplicationUserManager _userManager;
    public ApplicationUserManager UserManager
    {
        get
        {
            return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        set
        {
            _userManager = value;
        }
    }

    private ApplicationRoleManager _roleManager;
    public ApplicationRoleManager RoleManager
    {
        get
        {
            return _roleManager ?? HttpContext.GetOwinContext().Get<ApplicationRoleManager>();
        }
        private set
        {
            _roleManager = value;
        }
    }

and definition of ApplicationRoleManager which inherit of RoleManager

public class ApplicationRoleManager : RoleManager<IdentityRole>
{
    public ApplicationRoleManager(IRoleStore<IdentityRole,string> roleStore)
        : base(roleStore)
    {
    }

    public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
    {
        return new ApplicationRoleManager(new RoleStore<IdentityRole>(context.Get<ApplicationDbContext>()));
    }
}

if User don't has rolename Admin then (i dont know how) are moved to AccountController and method: public ActionResult Login(string returnUrl) It's Definition:

    [HttpGet]
    [AllowAnonymous]
    public ActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }

now I want to push info to this method if User aren't a Admin and give info "Hey! You don't have acces to this part of page, please Login to Admin account", then I expanded this method to this form:

    public ActionResult Login(string returnUrl)
    {

        if (returnUrl != null &&
            returnUrl.Contains("Admin") &&
            Request.IsAuthenticated &&
            !User.IsInRole("Admin"))
        {
            if (Request.IsAuthenticated)
                ViewBag.Info = "Hey! You don't have acces to this part of page, please Login to Admin account";
            else
                TempData["Info"] = "Hey! You don't have acces to this part of page, please Login to Admin account";
            return RedirectToAction("Index", "Home");
        }
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }

In my way I know, that all controller, which has name "Admin", f.e RolesAdminController, UserAdminController requirement Roles="Admin", but it isn't the coolest way :/

It works fine, but is other way to define any info if user (or guest) don't have access to controller?

Upvotes: 0

Views: 140

Answers (1)

Marek Woźniak
Marek Woźniak

Reputation: 1786

I searched and find the answer: simple create custom authorize class. It's good explained on this video: https://www.youtube.com/watch?feature=player_embedded&v=BsxUsyMSGeA or here: https://www.youtube.com/watch?v=vPyjmuT-lG4&list=PL5MZid1lr-vLd5ec3m1__Xn_1zvyjhOcD&index=26

or try to ask Uncle google for "create custom authorizeAttribute"

example:

public class RoleAttribute : AuthorizeAttribute
    {
        public string UserRole { get; set; }
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            return (httpContext.Request.IsAuthenticated && httpContext.User.IsInRole(UserRole));
        }

        //if AuthorizeCore return false
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            //add to session
            filterContext.RequestContext.HttpContext.Session["aa"] = "Hey! You haven't access!";
            string action = "";
            string controller = "";
            //get current action
            if (filterContext.Controller.ControllerContext.RouteData.Values["action"] != null)
            {
                action = filterContext.Controller.ControllerContext.RouteData.Values["action"].ToString();
            }
            //get current controller
            if (filterContext.Controller.ControllerContext.RouteData.Values["controller"] != null)
            {
                controller = filterContext.Controller.ControllerContext.RouteData.Values["controller"].ToString();
            }
            //add some values to temp data
            filterContext.Controller.TempData.Add("RoleErrors", "Hey! You don't have access!");

            //redirect to register method and for example add some info - returnUrl
            filterContext.Result = new RedirectToRouteResult(
                new System.Web.Routing.RouteValueDictionary(
                    new
                    {
                        controller = "Account",
                        action = "Register",
                        returnUrl = string.Format("{0}/{1}",controller,action)
                    })
                );
        }
    }

then in some controller you can use it as:

[Role(UserRole = "YourRole")]
public class MyController : Controller
{
     ...
}

and in AccountController you will be push into method:

public ActionResult Register(string returnUrl)
{
   ...
   ViewBag.Error = TempData["RoleErrors"] as string;
   return View();
}

and in View():

@if(ViewBag.Error != null)
{
   <p>@ViewBag.Error</p>
}

Upvotes: 1

Related Questions