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

.NET 6 ASP.NET Core应用调用API获取Azure AD令牌遇问题求助

解决方案:解决no account or login hint was passed to AcquireTokenSilent错误

这个错误的核心是调用令牌获取方法时,无法找到当前登录用户的账户上下文。以下是针对性的修复步骤:

1. 确保认证中间件配置正确

在Program.cs中,必须配置Azure AD认证并启用下游API令牌获取能力,同时添加令牌缓存:

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddInMemoryTokenCaches();

// 必须添加授权中间件
builder.Services.AddAuthorization();

// 注册HttpContextAccessor(非控制器场景需要)
builder.Services.AddHttpContextAccessor();

2. 检查AppSettings配置

确保appsettings.json中的Azure AD参数准确无误:

"AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "你的租户域名",
    "TenantId": "你的租户ID",
    "ClientId": "Web应用的客户端ID",
    "ClientSecret": "Web应用的客户端密钥",
    "CallbackPath": "/signin-oidc"
}

3. 控制器中正确获取令牌

在标记[Authorize]的控制器方法中,通过当前用户上下文获取账户,再调用令牌获取方法:

using Microsoft.Identity.Web;
using System.Net.Http.Headers;

[Authorize]
public class ApiCallController : Controller
{
    private readonly ITokenAcquisition _tokenAcquisition;

    public ApiCallController(ITokenAcquisition tokenAcquisition)
    {
        _tokenAcquisition = tokenAcquisition;
    }

    public async Task<IActionResult> CallProtectedApi()
    {
        // 获取当前登录用户的账户信息
        var userAccount = await _tokenAcquisition.GetAccountAsync(User);
        if (userAccount == null)
        {
            // 无有效账户,触发重新登录
            return Challenge();
        }

        // 替换为你的API范围
        string[] apiScopes = new[] { "api://你的API应用ID/你的自定义范围" };
        
        // 获取带指定范围的访问令牌
        string accessToken = await _tokenAcquisition.AcquireTokenForUser(apiScopes)
            .ExecuteAsync();

        // 调用API
        using var httpClient = new HttpClient();
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
        var apiResponse = await httpClient.GetAsync("你的API端点URL");
        
        // 处理API响应逻辑...
        return Ok(await apiResponse.Content.ReadAsStringAsync());
    }
}

4. 非控制器场景的处理

如果需要在服务类中获取令牌,需注入IHttpContextAccessor来获取当前用户上下文:

public class ApiCallService
{
    private readonly ITokenAcquisition _tokenAcquisition;
    private readonly IHttpContextAccessor _httpContextAccessor;

    public ApiCallService(ITokenAcquisition tokenAcquisition, IHttpContextAccessor httpContextAccessor)
    {
        _tokenAcquisition = tokenAcquisition;
        _httpContextAccessor = httpContextAccessor;
    }

    public async Task<string> GetApiAccessToken()
    {
        var currentUser = _httpContextAccessor.HttpContext?.User;
        if (currentUser == null || !currentUser.Identity.IsAuthenticated)
        {
            throw new UnauthorizedAccessException("用户未登录");
        }

        var userAccount = await _tokenAcquisition.GetAccountAsync(currentUser);
        string[] apiScopes = new[] { "api://你的API应用ID/你的自定义范围" };
        
        return await _tokenAcquisition.AcquireTokenForUser(apiScopes)
            .ExecuteAsync();
    }
}

5. Azure AD权限配置验证

  • 确保Web应用注册中已添加目标API的Delegated权限,并完成管理员同意(若需强制所有用户使用)
  • 确认API范围的格式正确:api://<API应用ID>/<范围名称>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 05:03:19