为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
相关产品推荐
相关产品推荐

