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

ASP.NET MVC/WebForms应用Azure AD多环境认证异常求助

ASP.NET多环境Azure AD认证重定向异常解决指南

问题背景

维护一个旧的ASP.NET WebForms/MVC应用,已完成生产环境的Azure AD认证配置。为在localhost及开发服务器上使用该认证,在Azure Portal的应用配置中添加了对应URL到“Redirect URIs”列表,但出现异常:每次打开生产环境链接时,都会被重定向到新增的本地或开发地址。

当前相关代码及配置如下:

Startup文件代码

Partial Public Class Startup

 Private Shared clientId As String = ConfigurationManager.AppSettings("ida:ClientId")
    Private Shared appKey As String = ConfigurationManager.AppSettings("ida:ClientSecret")
    Private Shared aadInstance As String = ConfigurationManager.AppSettings("ida:AADInstance")
    Private Shared tenantId As String = ConfigurationManager.AppSettings("ida:TenantId")
    Private Shared postLogoutRedirectUri As String = ConfigurationManager.AppSettings("ida:PostLogoutRedirectUri")

    Public Shared ReadOnly Authority As String = aadInstance + tenantId

    ' AAD Graph API的资源ID,用于请求调用Graph API的令牌
    Private graphResourceId As String = "https://graph.windows.net/"

    Public Sub ConfigureAuth(app As IAppBuilder)
        Dim db As New ApplicationDbContext()

        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType)
        app.UseKentorOwinCookieSaver()
        app.UseCookieAuthentication(New CookieAuthenticationOptions())

        ' 如果OpenID Connect响应中包含授权码,则兑换为访问令牌和刷新令牌并存储
        app.UseOpenIdConnectAuthentication(New OpenIdConnectAuthenticationOptions() With {
                .ClientId = clientId,
                .Authority = Authority,
                .PostLogoutRedirectUri = postLogoutRedirectUri,
                .Notifications = New OpenIdConnectAuthenticationNotifications() With {
                .AuthorizationCodeReceived = Function(context)
                                                 Dim code = context.Code
                                                 Dim credential As New ClientCredential(clientId, appKey)
                                                 Dim signedInUserID As String = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value
                                                 Dim authContext As New AuthenticationContext(Authority, New ADALTokenCache(signedInUserID))
                                                 Return authContext.AcquireTokenByAuthorizationCodeAsync(code, New Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId)

                                             End Function
                }
            })
    End Sub
End Class

Web.Config配置

<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="ida:ClientId" value="test" />
<add key="ida:AADInstance" value="https://login.microsoftonline.com/" />
<add key="ida:ClientSecret" value="test" />
<add key="ida:Domain" value="test.com" />
<add key="ida:TenantId" value="test" />
<add key="ida:PostLogoutRedirectUri" value="ProductionUrl" />
<add key="ValidationSettings:UnobtrusiveValidationMode" value="None" />

Azure AD Redirect URIs配置

Azure Portal中已添加生产地址、localhost地址及开发服务器地址,多个URI共存。

核心问题分析

  1. 重定向URI未按环境动态绑定:当前代码中AcquireTokenByAuthorizationCodeAsync使用请求URL作为重定向URI,Azure AD存在多个URI时,可能因会话缓存或匹配逻辑错误,导致生产环境请求被错误匹配到本地/开发URI。
  2. 登录流程未明确指定环境专属URI:仅固定了登出重定向地址,但登录环节的重定向逻辑依赖请求URL,加剧了匹配混乱。

解决步骤

1. 配置多环境专属重定向参数

通过Web.config变换功能,为每个环境配置独立的RedirectUri和PostLogoutRedirectUri:

  • 生产环境Web.config:
<add key="ida:PostLogoutRedirectUri" value="https://your-production-url.com" />
<add key="ida:RedirectUri" value="https://your-production-url.com" />
  • 开发环境Web.Debug.config:
<add key="ida:PostLogoutRedirectUri" xdt:Transform="Replace" xdt:Locator="Match(key)" value="http://localhost:xxxx" />
<add key="ida:RedirectUri" xdt:Transform="Replace" xdt:Locator="Match(key)" value="http://localhost:xxxx" />
  • 测试服务器环境Web.Test.config(需自定义配置文件):
<add key="ida:PostLogoutRedirectUri" xdt:Transform="Replace" xdt:Locator="Match(key)" value="https://your-test-server-url.com" />
<add key="ida:RedirectUri" xdt:Transform="Replace" xdt:Locator="Match(key)" value="https://your-test-server-url.com" />

2. 修改Startup代码,绑定环境专属URI

更新Startup类,读取配置中的RedirectUri,并在OpenID Connect配置和令牌获取逻辑中明确使用:

Partial Public Class Startup

    Private Shared clientId As String = ConfigurationManager.AppSettings("ida:ClientId")
    Private Shared appKey As String = ConfigurationManager.AppSettings("ida:ClientSecret")
    Private Shared aadInstance As String = ConfigurationManager.AppSettings("ida:AADInstance")
    Private Shared tenantId As String = ConfigurationManager.AppSettings("ida:TenantId")
    Private Shared postLogoutRedirectUri As String = ConfigurationManager.AppSettings("ida:PostLogoutRedirectUri")
    ' 新增读取环境专属RedirectUri
    Private Shared redirectUri As String = ConfigurationManager.AppSettings("ida:RedirectUri")

    Public Shared ReadOnly Authority As String = aadInstance + tenantId

    Private graphResourceId As String = "https://graph.windows.net/"

    Public Sub ConfigureAuth(app As IAppBuilder)
        Dim db As New ApplicationDbContext()

        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType)
        app.UseKentorOwinCookieSaver()
        app.UseCookieAuthentication(New CookieAuthenticationOptions())

        app.UseOpenIdConnectAuthentication(New OpenIdConnectAuthenticationOptions() With {
                .ClientId = clientId,
                .Authority = Authority,
                .PostLogoutRedirectUri = postLogoutRedirectUri,
                ' 指定当前环境的RedirectUri
                .RedirectUri = redirectUri,
                .Notifications = New OpenIdConnectAuthenticationNotifications() With {
                .AuthorizationCodeReceived = Function(context)
                                                 Dim code = context.Code
                                                 Dim credential As New ClientCredential(clientId, appKey)
                                                 Dim signedInUserID As String = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value
                                                 Dim authContext As New AuthenticationContext(Authority, New ADALTokenCache(signedInUserID))
                                                 ' 使用配置的RedirectUri而非请求URL,避免匹配错误
                                                 Return authContext.AcquireTokenByAuthorizationCodeAsync(code, New Uri(redirectUri), credential, graphResourceId)
                                             End Function
                }
            })
    End Sub
End Class

3. 校验Azure AD应用配置

确保Azure Portal中添加的所有Redirect URI与各环境配置的RedirectUri完全一致(包括协议、域名、端口),不要随意调整URI顺序,Azure AD会优先匹配代码中指定的URI。

4. 清除浏览器缓存与会话Cookie

因之前的错误重定向可能导致浏览器缓存旧会话,需清除生产环境域名的Cookie和缓存,避免残留影响。

验证方法

  • 本地开发:启动应用,测试登录后是否正确返回localhost地址
  • 测试服务器:部署测试版本,验证重定向逻辑正常
  • 生产环境:确认打开生产链接不会跳转到本地/开发地址,认证流程正常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 10:02:11