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

ASP.NET MVC中Windows身份验证与Azure AD OpenId共存及静默认证触发问题

解决Windows身份验证与Azure AD OIDC共存时的静默认证问题

当ASP.NET MVC应用同时启用Windows身份验证和Azure AD OpenID Connect认证时,Windows Auth的自动认证逻辑会抢先处理请求,导致OIDC的OnAuthorizationCodeReceived事件无法被自动触发,进而影响静默令牌刷新。以下是具体的解决步骤:

1. 调整认证中间件顺序

确保OIDC中间件在Windows身份验证中间件之前注册,让OIDC优先处理认证相关请求:

public void ConfigureAuth(IAppBuilder app)
{
    // 先注册OIDC中间件
    app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
    {
        ClientId = ClientId,
        Authority = Authority,
        RedirectUri = RedirectUri,
        PostLogoutRedirectUri = PostLogoutRedirectUri,
        OnAuthorizationCodeReceived = context => HandleSilentAuthentication(context),
        // 启用令牌刷新相关配置
        UseTokenLifetime = false,
        RefreshOnIssuerKeyNotFound = true,
        Scope = "openid profile offline_access" // 必须包含offline_access以获取刷新令牌
    });

    // 再注册Windows身份验证中间件
    app.UseWindowsAuthentication();
}

2. 在OnAuthorizationCodeReceived中实现静默认证逻辑

在该事件中手动利用刷新令牌获取新访问令牌,无需用户交互:

private async Task HandleSilentAuthentication(AuthorizationCodeReceivedNotification context)
{
    var credential = new ClientCredential(ClientId, ClientSecret);
    var authContext = new AuthenticationContext(Authority);

    // 从当前身份中获取已存储的刷新令牌
    var refreshToken = context.OwinContext.Authentication.User.FindFirst("refresh_token")?.Value;

    if (!string.IsNullOrEmpty(refreshToken))
    {
        try
        {
            // 使用刷新令牌获取新的访问令牌
            var result = await authContext.AcquireTokenByRefreshTokenAsync(refreshToken, credential, ResourceId);
            
            // 更新当前身份的令牌信息
            var identity = new ClaimsIdentity(context.AuthenticationTicket.Identity.AuthenticationType);
            identity.AddClaims(result.Claims);
            identity.AddClaim(new Claim("access_token", result.AccessToken));
            identity.AddClaim(new Claim("refresh_token", result.RefreshToken));
            
            context.AuthenticationTicket = new AuthenticationTicket(identity, context.AuthenticationTicket.Properties);
        }
        catch (AdalException)
        {
            // 刷新令牌失效时,重定向到登录页
            context.Response.Redirect("/Account/Login");
            context.HandleResponse();
        }
    }
}

3. 配置OIDC支持静默刷新

  • 在Azure AD应用注册中启用offline_access权限,并确保OIDC配置的Scope包含该权限。
  • 设置UseTokenLifetime = false,允许应用自定义令牌有效期,不依赖Azure AD返回的生命周期。
  • 开启RefreshOnIssuerKeyNotFound = true,当Azure AD密钥更新时自动触发令牌刷新。

4. 规避Windows Auth的自动抢占问题

如果Windows Auth仍抢先处理请求,可禁用其自动认证,改为在特定场景手动触发:

app.UseWindowsAuthentication(new WindowsAuthenticationOptions
{
    AutomaticAuthentication = false
});

之后在需要Windows身份验证的Action上添加特性:

[Authorize(AuthenticationSchemes = WindowsAuthenticationDefaults.AuthenticationScheme)]
public ActionResult WindowsOnlyAction()
{
    // 业务逻辑
    return View();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 14:41:03