ASP.NET Core Identity:如何重定义Forbid处理逻辑
解决Forbid()重定向逻辑自定义的问题
首先得点出你遇到的核心问题:你已经尝试配置OnRedirectToAccessDenied事件但没生效,这是因为**AddIdentity会自动注册一套独立的Cookie认证方案(IdentityConstants.ApplicationScheme),而你之前配置的ApplicationCookie对应的是默认的Cookie方案,两者不是同一个**。所以你的事件回调根本没被触发。
正确的配置方式
你需要直接针对Identity注册的Cookie方案来配置重定向事件,有两种可行方式:
方式一:在AddIdentity时直接配置Cookie的Events
public void ConfigureServices(IServiceCollection serviceCollection) { // 配置Identity,同时自定义Cookie的重定向事件 serviceCollection.AddIdentity<WebUser, IdentityRole<int>>(options => { options.SignIn.RequireConfirmedEmail = true; }) .AddEntityFrameworkStores<WebUserDbContext>() .AddDefaultTokenProviders() // 重点:绑定Identity Cookie的重定向事件 .AddCookie(options => { options.Events.OnRedirectToAccessDenied = context => { // 完全自定义重定向逻辑 // 1. 从自定义请求特性中获取值 var customReturnUrl = context.HttpContext.Features.Get<YourCustomFeature>()?.CustomReturnUrl; // 2. 构造重定向地址,优先用自定义值, fallback到当前请求路径 string redirectUrl = string.IsNullOrEmpty(customReturnUrl) ? "/AccessDenied" : $"/AccessDenied?returnUrl={Uri.EscapeDataString(customReturnUrl)}"; // 3. 添加自定义参数 redirectUrl += "&t=100"; context.Response.Redirect(redirectUrl); return Task.CompletedTask; }; }); // 其他常规配置 serviceCollection.AddDbContext<WebUserDbContext>(optionsBuilder => optionsBuilder.UseSqlServer(ApplicationSettings.WebUserStorageConfiguration.ConnectionString)); serviceCollection.AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }
方式二:单独针对Identity的Cookie Scheme配置
如果你不想在AddIdentity里嵌套配置,也可以单独指定Scheme来配置:
serviceCollection.AddCookie(IdentityConstants.ApplicationScheme, options => { options.Events.OnRedirectToAccessDenied = context => { // 自定义重定向逻辑示例 var customReturnUrl = context.HttpContext.Features.Get<YourCustomFeature>()?.CustomReturnUrl; string redirectUrl = $"/AccessDenied?returnUrl={Uri.EscapeDataString(customReturnUrl ?? context.Request.Path.ToString())}&t=100"; context.Response.Redirect(redirectUrl); return Task.CompletedTask; }; });
为什么之前的配置无效?
ConfigureApplicationCookie是针对ASP.NET Core默认的Cookie认证方案(CookieAuthenticationDefaults.AuthenticationScheme)的配置,但AddIdentity会注册自己的Cookie方案(IdentityConstants.ApplicationScheme)作为默认的认证方案。你的事件回调没有绑定到实际处理Forbid()的那个Cookie中间件上,自然不会触发。
额外注意事项
- 你必须保留
AddIdentity:因为你需要使用UserManager等API,同时Forbid()依赖它注册的Cookie认证方案——如果去掉,会因为找不到对应的认证处理逻辑抛出500错误。 - 对参数值进行编码:用
Uri.EscapeDataString()处理returnUrl这类参数,避免URL格式错误或注入问题。 - 灵活获取请求信息:通过
context.Request可以拿到当前请求的所有数据,结合自定义请求特性,能完全控制重定向的地址和参数。
内容的提问来源于stack exchange,提问作者Roman Pokrovskij
相关产品推荐
相关产品推荐

