Azure AD限制全部ASP.NET Core API,仅需管控部分端点如何解决
你遇到的报错不是后端权限拦截导致的,是Blazor WASM前端的AuthorizationMessageHandler默认会给所有绑定了该Handler的HTTP请求尝试附加访问令牌,未登录状态下无法获取令牌就会直接抛出AccessTokenNotAvailableException,请求根本不会发送到后端,所以你修改后端注解甚至关闭鉴权中间件都不会生效。
以下是完整配置方案:
1 前端配置(核心修改点)
官方默认模板会给全局HttpClient绑定BaseAddressAuthorizationMessageHandler,要求所有发往后端的请求都带令牌,你需要拆分两类HttpClient:
- 带授权处理的HttpClient:仅用于需要登录才能访问的受保护接口
- 普通HttpClient:用于匿名访问的公开接口
前端Program.cs示例代码:
// 原有带授权的HttpClient,用于受保护接口 builder.Services.AddHttpClient("ProtectedAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)) .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>(); // 新增不带授权处理的HttpClient,用于匿名接口 builder.Services.AddHttpClient("AnonymousAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)); // 如果你用了Typed Client,同理给匿名接口单独写不带授权Handler的Typed Client即可
前端调用示例:
注入IHttpClientFactory,根据接口类型选择对应的HttpClient:
@inject IHttpClientFactory _httpClientFactory // 调用匿名接口 var anonymousClient = _httpClientFactory.CreateClient("AnonymousAPI"); var result = await anonymousClient.GetFromJsonAsync<List<WikiPage>>("api/wikipages"); // 调用受保护接口 var protectedClient = _httpClientFactory.CreateClient("ProtectedAPI"); var privateResult = await protectedClient.GetFromJsonAsync<UserInfo>("api/user/profile");
2 后端配置
不要注释app.UseAuthentication();和app.UseAuthorization();,保持正常启用,顺序必须放在UseRouting之后、MapControllers之前。
接口权限控制只需要通过注解实现即可:
- 若控制器下大部分是公开接口:控制器不加
[Authorize],仅给需要保护的少数Action加[Authorize]和[RequiredScope]注解 - 若控制器下大部分是受保护接口:控制器加
[Authorize]和[RequiredScope],仅给需要公开的Action加[AllowAnonymous]注解
后端控制器示例:
[Route("api/wikipages")] [ApiController] public class WikiPageController : ControllerBase { // 公开接口,允许匿名访问 [HttpGet] [AllowAnonymous] public async Task<IActionResult> GetAllPages() { // 业务逻辑 } // 受保护接口,需要登录且有对应Scope才能访问 [HttpPost] [Authorize] [RequiredScope(RequiredScopesConfigurationKey = "AzureAd:Scopes")] public async Task<IActionResult> CreatePage([FromBody] WikiPageDto dto) { // 业务逻辑 } }
内容的提问来源于stack exchange,提问作者Joben
相关产品推荐
相关产品推荐

