You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为ASP.NET MVC两个不同区域配置Owin身份验证的问题

ASP.NET MVC 按区域跳转对应登录页并传递ReturnUrl解决方案

1. 完善自定义AreaAuthorizeAttribute

重写HandleUnauthorizedRequest方法,根据当前请求的区域动态生成带ReturnUrl的登录跳转地址:

Imports System.Web.Mvc
Imports System.Web

Public Class AreaAuthorizeAttribute
    Inherits AuthorizeAttribute

    Protected Overrides Sub HandleUnauthorizedRequest(filterContext As AuthorizationContext)
        ' 获取当前请求所属区域
        Dim areaName = filterContext.RouteData.DataTokens("area")?.ToString()
        ' 获取当前请求的绝对路径作为ReturnUrl
        Dim returnUrl = filterContext.HttpContext.Request.Url?.AbsolutePath

        ' 根据区域选择对应的登录Action
        Dim loginAction = If(String.Equals(areaName, "Homeowners", StringComparison.OrdinalIgnoreCase), 
                            "Login", "VendorLogin")
        ' 构造带Url编码ReturnUrl的登录地址
        Dim loginUrl = $"/LoginOut/{loginAction}?ReturnUrl={HttpUtility.UrlEncode(returnUrl)}"

        ' 执行跳转
        filterContext.Result = New RedirectResult(loginUrl)
    End Sub

2. 替换区域控制器的授权标记

在Homeowners和Vendors区域的所有需要授权的控制器上,用[AreaAuthorize]替换默认的[Authorize]标记,例如:

<AreaAuthorize>
Public Class ManageController
    Inherits Controller
    ' 房主区域的控制器逻辑
End Class
<AreaAuthorize>
Public Class VendorsManageController
    Inherits Controller
    ' 供应商区域的控制器逻辑
End Class

3. 调整登录控制器的跳转逻辑

在LoginOutController的Login和VendorLogin POST方法中,验证用户身份成功后,根据ReturnUrl跳转回原请求页面:

<HttpPost>
Public Function Login(model As LoginViewModel, returnUrl As String) As ActionResult
    If ModelState.IsValid Then
        ' 验证用户逻辑(略)
        If IsValidUser(model) Then
            ' 验证ReturnUrl是否为本地Url,防止开放重定向攻击
            If Not String.IsNullOrEmpty(returnUrl) AndAlso Url.IsLocalUrl(returnUrl) Then
                Return Redirect(returnUrl)
            Else
                ' 默认跳转到房主区域的首页
                Return RedirectToAction("Landing", "Manage", New With {.area = "Homeowners"})
            End If
        End If
    End If
    Return View(model)
End Function

<HttpPost>
Public Function VendorLogin(model As VendorLoginViewModel, returnUrl As String) As ActionResult
    If ModelState.IsValid Then
        ' 验证供应商用户逻辑(略)
        If IsValidVendor(model) Then
            If Not String.IsNullOrEmpty(returnUrl) AndAlso Url.IsLocalUrl(returnUrl) Then
                Return Redirect(returnUrl)
            Else
                ' 默认跳转到供应商区域的首页
                Return RedirectToAction("VendorsLanding", "VendorsManage", New With {.area = "Vendors"})
            End If
        End If
    End If
    Return View(model)
End Function

4. 清理Startup.Auth中的硬编码登录路径

如果之前在ConfigureAuth中硬编码了登录跳转地址,注释或删除该配置,让自定义授权属性接管跳转逻辑:

' 注释掉原硬编码配置
' app.UseCookieAuthentication(New CookieAuthenticationOptions() With {
'     .LoginPath = New PathString("/LoginOut/Login")
' })

关键细节说明

  • 区域名称判断使用StringComparison.OrdinalIgnoreCase,避免大小写敏感问题
  • 对ReturnUrl进行UrlEncode处理,防止特殊字符导致的跳转异常
  • 登录成功时验证ReturnUrl是否为本地Url,避免安全风险

内容的提问来源于stack exchange,提问作者gchq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 21:12:38