如何在AuthorizationMiddlewareResultHandler的HandleAsync方法中生成Action的URL
在.NET 7授权中间件中生成Action的绝对URL
问题背景
在.NET Framework中,自定义Authorization过滤器可通过RedirectToActionResult直接重定向到指定Action;但在.NET 7实现IAuthorizationMiddlewareResultHandler的授权中间件里,需要替换硬编码的相对URL,生成ASP.NET Core自动处理的绝对URL,且当前场景不在控制器内,无法直接使用Url.Action。
解决方案
使用ASP.NET Core内置的LinkGenerator服务,它专门用于非控制器场景(如中间件、服务)生成URL,支持生成包含协议、主机信息的绝对路径。
步骤1:修改中间件,注入LinkGenerator
更新TestAuthorizationMiddleware类,通过构造函数注入LinkGenerator,并利用它生成目标Action的绝对URL:
public class TestAuthorizationMiddleware : IAuthorizationMiddlewareResultHandler { private readonly AuthorizationMiddlewareResultHandler _defaultHandler; private readonly LinkGenerator _linkGenerator; public TestAuthorizationMiddleware(LinkGenerator linkGenerator) { _defaultHandler = new AuthorizationMiddlewareResultHandler(); _linkGenerator = linkGenerator; } public async Task HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) { if (authorizeResult.Challenged && policy.AuthenticationSchemes.Count == 0) { // 生成目标Action的绝对URL var absoluteUrl = _linkGenerator.GetUriByAction( context, action: "ChooseAuthenticationMethod", controller: "Account", scheme: context.Request.Scheme, host: context.Request.Host); // 确保URL生成成功后再重定向,否则 fallback 到相对路径 if (!string.IsNullOrWhiteSpace(absoluteUrl)) { context.Response.Redirect(absoluteUrl); } else { context.Response.Redirect("Account/ChooseAuthenticationMethod"); } } else { await _defaultHandler.HandleAsync(next, context, policy, authorizeResult); } } }
步骤2:注册中间件服务
在Program.cs中,将自定义的IAuthorizationMiddlewareResultHandler注册为单例服务:
builder.Services.AddSingleton<IAuthorizationMiddlewareResultHandler, TestAuthorizationMiddleware>();
说明
LinkGenerator.GetUriByAction方法通过传入HttpContext、Action名称、控制器名称,自动拼接出符合当前请求协议(http/https)和主机的绝对URL。- 显式指定
scheme和host参数可确保生成的URL与当前请求上下文完全一致,避免环境差异导致的URL错误。
内容的提问来源于stack exchange,提问作者Philip Stratford
相关产品推荐
相关产品推荐

