I'm using ASP.NET Identity 2 in an ASP.NET MVC 5 application with OWIN. As of now, if an authenticated user tries to access an action he does not have a role for, he's redirected to the login page. How can I make it so authenticated users get an AccessDenied page in that case, but unauthenticated users still get sent to login page?
ConfigureAuth method as follows:
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
app.UseSaml2Authentication(GetSamlOptions());
}
Try this custom authorize attribute, it does not redirect but replace the content instead so the url is intact, and also supports ajax request:
public class AppAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var isAuthorized = base.AuthorizeCore(httpContext);
if (!isAuthorized)
{
return false;
}
// do another checks here...
}
// This will be executed when AuthorizeCore returns false
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
var urlHelper = new UrlHelper(filterContext.RequestContext);
filterContext.HttpContext.Response.StatusCode = 403;
filterContext.Result = new JsonResult
{
Data = new
{
ErrorMessage = "Unauthorized"
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
filterContext.Result = new ViewResult
{
ViewName = "~/Views/Error/AccessDenied.cshtml"
};
}
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
}
Replace all [Authorize]
with your custom attribute [AppAuthorize]
You can use custom [DataAnnotations]
based on roles to give access to certain users. Something like:
[OnlyAllowedAttribute("Roles=Admin")]
public IActionResult OnlyAuthenticatedUsers()
{
return View();
}
public class OnlyAllowedAttribute: AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if(Threading.Thread.CurrentPrincipal.Identity.IsAuthenticated)
{
if(filterContext.Result is HttpUnauthorizedResult)
{
filterContext.Result = new RedirectResult("~/Account/AcessDenied");
}
}
else
{
filterContext.Result = new RedirectResult("~/Account/Login");
}
}
}
I implemented a custom authorization attribute as follows:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public sealed class CustomAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext.Result is HttpUnauthorizedResult)
{
var route_values = new RouteValueDictionary
{
["controller"] = "Account"
};
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
route_values["action"] = "AccessDenied";
}
else
{
route_values["action"] = "Login";
route_values["returnUrl"] = filterContext.HttpContext.Request.Url.PathAndQuery;
}
filterContext.Result = new RedirectToRouteResult(route_values);
}
}
}
I'm still open to any answer that leverages some OWIN configuration value.
Thanks to everyone that helped.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.