I would like to redirect the unauthorized user to a unauthorizedpage. Authorization is Roles based. For example [Authorize(Roles = "Admin")] I'm looking for a general solution. I don't want to write a redirect in every controllor/endpoint. I'm using Windows Auth with the Negotiate protocol.
I'm using the AuthorizeAttribute. When the user is unauthorized for a view then the application shows a blank HTML page to the user.
I tried multiple CustomAttributes, Configure AccesDeniedPaths, HandleUnauthorizedRequest. But every way ended in a blank HTML page.
I hope someone has an solution.
CodePudding user response:
ASP.NET has a defualt [Authorize]
attribute which you can add to an arbitrary action.
Eg:
[HttpGet]
[Authorize]
public async Task<ActionResult<IEnumerable<Classes>>> GetClasses()
{
return await _context.Classes.ToListAsync();
}
This will by default redirect the user to the login page if an unauthorized user tries to access a forbidden page.
However, if you want to redirect to a custom page. You could try writing a custom filter attribute like this.
public class CustomAuthorizeAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.User.Identity == null || !filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Result = new RedirectResult(System.Web.Security.FormsAuthentication.LoginUrl "?returnUrl="
filterContext.HttpContext.Server.UrlEncode(filterContext.HttpContext.Request.RawUrl));
}
//Check user rights here
if (userNotRight)
{
filterContext.HttpContext.Response.StatusCode = 302;
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
and use it in a controller like this,
[HttpGet]
[CustomAuthorize]
public async Task<ActionResult<IEnumerable<Classes>>> GetClasses()
{
return await _context.Classes.ToListAsync();
}
If you would like to authorize based on roles for the custom filter attribute. You could either
1. write a custom authorize attribute and add it along with the filter attribute.
public class AuthorizeAdmin : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
// The user is not authenticated
return false;
}
var user = httpContext.User;
if (user.IsInRole("Admin")) // Your desired role
{
return true;
}
}
}
controller:
[HttpGet]
[CustomAttribute]
[AuthorizeAdmin]
public async Task<ActionResult<IEnumerable<Classes>>> GetClasses()
{
return await _context.Classes.ToListAsync();
}
2. you could directly check it along with the custom filter attribute
public class CustomAuthorizeAttribute : ActionFilterAttribute
{
// Check if is in "Admin" role
var authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
// The user is not authenticated
return false;
}
var user = httpContext.User;
if (user.IsInRole("Admin")) // Your desired role
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.User.Identity == null || !filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Result = new
RedirectResult(System.Web.Security.FormsAuthentication.LoginUrl
"?returnUrl="
filterContext.HttpContext.Server.UrlEncode(filterContext.HttpContext.Request.RawUrl));
}
//Check user rights here
if (userNotRight)
{
filterContext.HttpContext.Response.StatusCode = 302;
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
}
controller:
[HttpGet]
[CustomAttribute]
public async Task<ActionResult<IEnumerable<Classes>>> GetClasses()
{
return await _context.Classes.ToListAsync();
}
CodePudding user response:
CustomAuthorizeAttribute
public class CustomAuthorizeAttribute : ActionFilterAttribute
{
public string Roles { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//if user isn't logged in.
if (filterContext.HttpContext.User.Identity == null || !filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Result = new RedirectResult("/Unauthorized/");
}
var user = filterContext.HttpContext.User;
//Check user rights here
if (!user.IsInRole(Roles))
{
filterContext.HttpContext.Response.StatusCode = 403;
filterContext.Result = new RedirectResult("/Unauthorized/");
}
}
}
Controller
[CustomAuthorize(Roles = "Admin")]
[HttpGet]
public IActionResult Index()
{
return View();
}