通过 Azure API 管理调用 API 时 User.Identity.Name 为空

User.Identity.Name is empty when API is called through Azure API Management

如果我通过 API 管理从客户端(例如本机控制台应用程序)调用我的 API,我的 User.Identity.Name 为空并且 IsAuthenticated 为 False在后端 API.

如果我通过 API 管理门户网页(Try It 测试门户)调用我的 API,我的服务器端 API 代码能够看到我的 User.Identity (User.Identity.Name, User.Identity.IsAuthenticated)。

在我的客户端,我正在获取一个令牌,然后调用通过 Azure API 管理公开的 API。

HttpClientHandler handler = new HttpClientHandler
{
    UseDefaultCredentials = true
};

client = new HttpClient(handler);
authContext = new AuthenticationContext(AADInstance);

PlatformParameters platformParameters = new PlatformParameters(PromptBehavior.Auto);
AuthenticationResult authResult = await authContext.AcquireTokenAsync(apiResourceId, clientId, redirectUrl, platformParameters);

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authResult.AccessTokenType, authResult.AccessToken);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Connection.Add("Keep-Alive");
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);
client.DefaultRequestHeaders.Add("Host", "...");

client.BaseAddress = new Uri(baseAddress);

var response = await GetResponseAsync(baseAddress + "Diagnostics");

在服务器上,我试图获取调用API的User.Identity(我的API当然不知道它是通过API 管理门户)。 User.Identity.Name 为空,AuthenticationType 为空,IsAuthenticated 标志为 False。如果我通过 API 管理门户 "Try It" 函数调用我的 API,这些值将被正确填充。

HttpContext context = HttpContext.Current;
userName = User.Identity.Name; //is empty
ClaimsIdentity claimsIdentity = (ClaimsIdentity)User.Identity;
items.Add($"Authentication Type: '{claimsIdentity.AuthenticationType}'"); // is empty
items.Add($"Is Authenticated: {claimsIdentity.IsAuthenticated}"); // is False

API 默认情况下管理不会触及授权 header,因此如果客户端发送 JWT 令牌,则后端应该原封不动地接收它。

您可以尝试使用 APIM 中的 validate-jwt 策略来验证客户端发送给您的令牌是否确实有效。

您的控制台客户端使用的 clientId 是否与设置 Try It 门户时使用的相同?如果不是,是否已针对 AAD 中的后端授权控制台 clientId?

您是否正在从 APIM 向后端执行 https?如果没有 https,凭据可能会被忽略。

问题是作为不记名令牌请求的一部分传入的资源 ID。它必须是后端 API 的 App ID URI,而不是 API 管理门户。