gpt4 book ai didi

当用户登录时,ASP.NET 成员(member)登录重定向到未经授权的

转载 作者:行者123 更新时间:2023-12-01 23:34:23 24 4
gpt4 key购买 nike

我们有一个使用 ASP.net 成员(member)资格来提供基本登录机制的应用程序。一切正常,但最近我们发现,如果您在登录时尝试进入登录页面,您将被重定向到“未经授权”页面。

Example user flow.

User goes to secured page (whole application requires login, there's not even a home page you can visit, just redirects straight to login). This redirects them to https://www.example.com/Account/Login.

User logs in and is redirected to home page https://www.example.com/. They are logged in and everything works fine.

User clicks a bookmark that happens to be set to https://www.example.com/Account/Login

User is redirected to generic Unauthorized page.

我有<Authorize()>我的 AccountController 上的属性,但 <AllowAnonymous()>正如我们之前看到的,“登录”操作上的属性在您未登录时工作正常,但当您登录时,它似乎会有点困惑。

AccountController

<Authorize()> _
Public Class AccountController
'''other functions go here'''

<AllowAnonymous()> _
Public Function Login(ByVal returnUrl As String) As ActionResult
ViewData("ReturnUrl") = returnUrl
Return View()
End Function

AuthorizeRedirect过滤器

<AttributeUsage(AttributeTargets.[Class] Or AttributeTargets.Method)> _
Public Class AuthorizeRedirect
Inherits AuthorizeAttribute
Private Const IS_AUTHORIZED As String = "isAuthorized"

Public RedirectUrl As String = "~/Home/Unauthorized"

Protected Overrides Function AuthorizeCore(httpContext As System.Web.HttpContextBase) As Boolean
Dim isAuthorized As Boolean = MyBase.AuthorizeCore(httpContext)

httpContext.Items.Add(IS_AUTHORIZED, isAuthorized)

Return isAuthorized
End Function

Public Overrides Sub OnAuthorization(filterContext As AuthorizationContext)
MyBase.OnAuthorization(filterContext)

Dim isAuthorized = If(filterContext.HttpContext.Items(IS_AUTHORIZED) IsNot Nothing, Convert.ToBoolean(filterContext.HttpContext.Items(IS_AUTHORIZED)), False)

If Not isAuthorized AndAlso filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated Then
filterContext.RequestContext.HttpContext.Response.Redirect(RedirectUrl)
End If
End Sub
End Class

看到这一切,我认为最简单的解决方案是检查用户是否已经在我的登录操作中登录并自己将其重定向,就像这样。

<AllowAnonymous()> _
Public Function Login(ByVal returnUrl As String) As ActionResult
If User.Identity.IsAuthenticated() Then
Return RedirectToAction("Index", "Home")
End If
ViewData("ReturnUrl") = returnUrl
Return View()
End Function

但是AuthorizeFilter总是先跳出来,这是可以理解的,但我不太清楚最后一个缺失的部分。我想要的只是如果用户在登录时进入登录屏幕,而不是显示“您无权查看此页面”,而是将其重定向到主页。我错过了什么?

<小时/>

编辑以使事情更清晰

登录后,我会转到 /Account/Login 。这个302将我重定向到 /Home/Unauthorized (我的自定义页面)。不过,我仍然处于登录状态。

网络请求

Network request to Login page, which 302 redirects to Unauthorized

未经授权的页面。请注意,突出显示的黄色部分显示我仍处于登录状态。只有在您登录时才会出现此信息。未登录时,您将看不到任何信息。

Unauthorized page

问题似乎是,当我已经登录并尝试访问包含 [AllowAnonymous] 的页面时,应用程序不知道该怎么做。其上的属性。如果有的话,我在这里看到的行为比它实际上再次给我一个登录页面更好,因为这会令人困惑,但它仍然不理想。

<小时/>

编辑 2 - 逐行单步执行代码

以下是逐行执行代码的结果。

/Account/Login登录时。

OnAuthorization 中的第一个断点子地址 AuthorizeRedirect过滤。

Public Overrides Sub OnAuthorization(filterContext As AuthorizationContext)
MyBase.OnAuthorization(filterContext)

Dim isAuthorized = If(filterContext.HttpContext.Items(IS_AUTHORIZED) IsNot Nothing, Convert.ToBoolean(filterContext.HttpContext.Items(IS_AUTHORIZED)), False)

If Not isAuthorized AndAlso filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated Then
filterContext.RequestContext.HttpContext.Response.Redirect(RedirectUrl)
End If
End Sub

Dim isAuthorized 开头的行返回 False。 filterContext.HttpContext.Items(IS_AUTHORIZED)什么都没有(项目列表中不存在)。

这意味着下一个 If 语句的计算结果为 True(Not isAuthorized AndAlso ...IsAuthenticated),导致重定向到 RedirectUrl .

发生这种情况后,它似乎会返回相同的步骤,但这次它的计算结果为 false,这意味着不会发生重定向,尽管我猜测这只是“未经授权”页面加载并通过再次使用相同的代码。

我尝试将以下 block 添加到 Login 的顶部AccountController的功能.

    If User.Identity.IsAuthenticated() Then
Return RedirectToAction("Index", "Home")
End If

但是,当然,由于过滤器是在操作发生之前运行的,所以直到之后它已经将我重定向到 Unauthorized 之前,此代码才会被命中。 (通过逐步验证)。

最佳答案

AuthorizationAttribute 的基类在其 OnAuthorization 方法中包含以下代码:

bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true);

if (skipAuthorization)
{
return;
}

if (AuthorizeCore(filterContext.HttpContext))
// ...

因此,如果 Controller 操作定义了 AllowAnonymousAttribute,则您的 AuthorizeCore 方法将不会被调用。

因为 filterContext.HttpContext.Items(IS_AUTHORIZED) 永远不会被设置。

您只需复制 here 中的代码即可实现OnAuthorization而不调用基类。这样您就可以按照您想要的方式处理缓存。

顺便说一句,我的印象是,如果授权失败,请求管道中的后续进程无论如何都会重定向到登录页面。这就是 OnAuthorization 的基本实现将 filterContext.Result 设置为新的 HttpUnauthorizedResult 实例的原因。因此,尚不完全清楚为什么要覆盖 OnAuthorization 并首先进行重定向。如果您想要某种自定义授权代码,只需从 AuthorizeCore 返回 truefalse 就足够了。

关于当用户登录时,ASP.NET 成员(member)登录重定向到未经授权的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38640354/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com