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

如何让ASP.NET Identity强制使用小写路由?

让ASP.NET Core Identity使用小写路由的解决方案

方法1:配置Cookie认证路径+Identity UI路由别名

如果使用的是官方Identity UI模板,可以直接指定Cookie认证的跳转路径,并为Identity页面配置小写路由别名,从根源上改变重定向目标:

builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<IdentityUserDbContext>()
    .AddSignInManager()
    .AddDefaultTokenProviders();

// 配置Cookie认证的小写跳转路径
builder.Services.ConfigureApplicationCookie(options =>
{
    options.LoginPath = "/account/login";
    options.LogoutPath = "/account/logout";
    options.AccessDeniedPath = "/account/accessdenied";
    // 按需添加其他Identity相关路径,如注册、找回密码等
});

// 为Identity区域页面绑定小写路由
builder.MapRazorPages()
    .AddRazorPagesOptions(options =>
    {
        // 保留原有授权规则
        options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
        options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
        
        // 为每个Identity页面映射小写路由
        options.Conventions.AddAreaPageRoute("Identity", "/Account/Login", "account/login");
        options.Conventions.AddAreaPageRoute("Identity", "/Account/Logout", "account/logout");
        options.Conventions.AddAreaPageRoute("Identity", "/Account/AccessDenied", "account/accessdenied");
        options.Conventions.AddAreaPageRoute("Identity", "/Account/Register", "account/register");
        options.Conventions.AddAreaPageRoute("Identity", "/Account/ForgotPassword", "account/forgotpassword");
    });

方法2:自定义SignInManager重定向逻辑

如果需要更灵活的URL控制,可以重写SignInManager中生成重定向URL的方法,强制转换为小写:

首先创建自定义SignInManager:

public class LowercaseSignInManager<TUser> : SignInManager<TUser> 
    where TUser : class
{
    public LowercaseSignInManager(
        UserManager<TUser> userManager,
        IHttpContextAccessor contextAccessor,
        IUserClaimsPrincipalFactory<TUser> claimsFactory,
        IOptions<IdentityOptions> optionsAccessor,
        ILogger<SignInManager<TUser>> logger,
        IAuthenticationSchemeProvider schemes,
        IUserConfirmation<TUser> confirmation) 
        : base(userManager, contextAccessor, claimsFactory, optionsAccessor, logger, schemes, confirmation)
    {
    }

    // 重写登录重定向方法,转换为小写
    public override Task<string> RedirectToLoginAsync(string returnUrl = null)
    {
        var originalUrl = base.RedirectToLoginAsync(returnUrl).Result;
        return Task.FromResult(originalUrl.ToLowerInvariant());
    }

    // 按需重写其他重定向方法
    public override Task<string> RedirectToLogoutAsync(string returnUrl = null)
    {
        var originalUrl = base.RedirectToLogoutAsync(returnUrl).Result;
        return Task.FromResult(originalUrl.ToLowerInvariant());
    }

    public override Task<string> RedirectToAccessDeniedAsync(string returnUrl = null)
    {
        var originalUrl = base.RedirectToAccessDeniedAsync(returnUrl).Result;
        return Task.FromResult(originalUrl.ToLowerInvariant());
    }
}

然后在Program.cs中替换默认的SignInManager:

builder.Services.AddScoped<SignInManager<ApplicationUser>, LowercaseSignInManager<ApplicationUser>>();

方法3:自定义Identity控制器的路由配置

如果是自己编写的Account控制器,直接在路由配置中指定小写路径即可:

// 为Account控制器配置小写路由
app.MapControllerRoute(
    name: "identity",
    pattern: "account/{action=Login}",
    defaults: new { controller = "Account" });

为什么LowercaseUrls = true不生效?

builder.Services.AddRouting(options => options.LowercaseUrls = true)仅对路由系统生成的常规链接(如Url.Action生成的地址)生效,但Identity的重定向URL是由Cookie认证选项或SignInManager的默认硬编码逻辑生成,并未经过该路由配置的小写转换,所以单独设置无法改变Identity的重定向路径。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 07:29:52