Reputation: 1786
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
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