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

ASP.NET Core 6部署IIS后Identity认证异常:Question控制器无法访问

IIS部署ASP.NET Core 6 Identity授权异常:仅特定控制器重定向到登录页

问题描述

在IIS上部署的ASP.NET Core 6项目中,使用Identity处理认证与授权时出现异常:登录成功后多数MVC控制器可正常访问,但访问Question控制器的/Questions/Asked/List(对应MyQuestions方法)时,即便用户处于已认证状态,仍会被重定向到/Account/Login页面。本地Visual Studio 2022运行完全正常,移除授权特性、测试其他带授权特性的控制器后问题依旧。

排查与解决方案

1. 中间件顺序错误

本地化中间件UseRequestLocalization被放置在认证中间件之后,可能导致文化Cookie处理干扰身份认证Cookie的读取逻辑,进而引发认证失效。

修复方案:调整中间件顺序,将UseRequestLocalization移至UseRouting之前:

var app = builder.Build();

// ... 环境配置代码 ...

// 先执行本地化配置
var localizationOptions = app.Services.CreateScope().ServiceProvider
    .GetService<IOptions<RequestLocalizationOptions>>().Value;
app.UseRequestLocalization(localizationOptions);

app.UseSession();
app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

// ... 其他中间件及路由配置 ...

2. 自定义授权特性未处理未认证场景

自定义Authorization特性中未先校验用户是否已认证,若认证Cookie未正确读取,访问User.Claims会抛出异常,被框架捕获后触发默认登录重定向,而非预期的访问拒绝页面。

修复方案:增强授权特性逻辑,先校验认证状态:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class Authorization : Attribute, IAuthorizationFilter
{
    public Claim Claim { get; set; }

    public Authorization(string claimType)
    {
        this.Claim = new Claim(claimType, "true");
    }

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        // 先校验用户是否已认证
        if (!context.HttpContext.User.Identity?.IsAuthenticated ?? true)
        {
            context.Result = new ChallengeResult();
            return;
        }

        try
        {
            var userHasClaim = context.HttpContext.User.Claims.Any(x => 
                string.Equals(x.Type, this.Claim.Type, StringComparison.OrdinalIgnoreCase) && 
                string.Equals(x.Value, this.Claim.Value, StringComparison.OrdinalIgnoreCase));
            
            if (!userHasClaim)
            {
                context.Result = new RedirectResult("/Error/Access-Denied");
            }
        }
        catch
        {
            context.Result = new RedirectResult("/Error/Access-Denied");
        }
    }
}

3. IIS环境下Cookie配置缺失

生产环境中Cookie的SameSite、Secure等属性未明确配置,可能导致Cookie无法在IIS环境下正确传递。

修复方案:完善Cookie配置:

service.ConfigureApplicationCookie((cookie) =>
{
    cookie.Cookie.HttpOnly = true;
    cookie.ExpireTimeSpan = TimeSpan.FromMinutes(20);
    cookie.SlidingExpiration = true;
    cookie.Cookie.SameSite = SameSiteMode.Lax;
    cookie.Cookie.SecurePolicy = CookieSecurePolicy.Always; // 启用HTTPS时设置
    cookie.LoginPath = "/Account/Login";
    cookie.AccessDeniedPath = "/Error/Access-Denied";
});

4. Session与认证Cookie冲突

Session Cookie与Identity认证Cookie名称默认可能重叠,在IIS环境下引发Cookie隔离问题。

修复方案:自定义Session Cookie名称:

service.AddSession((options) =>
{
    options.IOTimeout = TimeSpan.FromMinutes(20);
    options.IdleTimeout = TimeSpan.FromMinutes(20);
    options.Cookie.Name = ".ForumApp.Session"; // 自定义名称避免冲突
});

5. 路由匹配优先级问题

自定义路由[Route("/Questions/Asked/List")]与默认路由规则可能存在匹配冲突,导致请求未正确映射到目标方法。

修复方案:调整路由配置,确保唯一性:

[Route("[controller]")]
public class QuestionController : Controller
{
    [Authorization(ClaimList.MyQuestions)]
    [HttpGet("Asked/List")]
    public async Task<IActionResult> MyQuestions()
    {
        // ... 原有逻辑 ...
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 15:41:13