如何显示拒绝访问而不是重定向到登录页面?
Posted
技术标签:
【中文标题】如何显示拒绝访问而不是重定向到登录页面?【英文标题】:How to show Access Denied instead of redirecting to login page? 【发布时间】:2020-06-19 07:46:28 【问题描述】:我在带有 OWIN 的 ASP.NET MVC 5 应用程序中使用 ASP.NET Identity 2。到目前为止,如果经过身份验证的用户尝试访问他没有角色的操作,他将被重定向到登录页面。在这种情况下,如何使经过身份验证的用户获得 AccessDenied 页面,但未经身份验证的用户仍会被发送到登录页面?
ConfigureAuth方法如下:
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());
【问题讨论】:
更新("/Account/Login")
到您的拒绝访问视图。
@LinkedListT 这不适用于未经身份验证的用户!
您是否在控制器/动作之上指定任何角色?
是的,许多操作都有Authorize
具有特定角色。
我认为您最好的选择是创建一个继承自 AuthorizeAttribute
的类并覆盖 OnAuthorization()
。然后在该方法中,检查请求是否经过身份验证且未授权。
【参考方案1】:
试试这个自定义的授权属性,它不会重定向而是替换内容,所以 url 是完整的,并且还支持 ajax 请求:
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);
将所有[Authorize]
替换为您的自定义属性[AppAuthorize]
【讨论】:
您过滤的是IsAjaxRequest
,而不是IsAuthenticated
!
它首先检查IsAuthenticated
是否为真,然后检查是否IsAjaxRequest
【参考方案2】:
您可以根据角色使用自定义[DataAnnotations]
来授予特定用户访问权限。类似的东西:
[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");
https://***.com/a/1279854/9936356
【讨论】:
我认为您还必须检查是否未经身份验证。在您的代码中,这两种情况都会发生。 不是从线程获取Identity
,我不应该从filterContext.HttpContext.user.Identity
获取它吗?【参考方案3】:
我实现了一个自定义的授权属性如下:
[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);
我仍然愿意接受任何利用某些 OWIN 配置值的答案。
感谢所有提供帮助的人。
【讨论】:
以上是关于如何显示拒绝访问而不是重定向到登录页面?的主要内容,如果未能解决你的问题,请参考以下文章
登录成功后访问登录页面时出现Spring安全访问被拒绝消息。它应该重定向到默认页面
如何使授权属性返回自定义 403 错误页面而不是重定向到登录页面