我有一个托管的 Blazor WebAssembly 应用程序,我正在尝试从 Azure DevOps 提取数据。我们目前使用 PAT 进行访问,但我希望人们改用他们的 Entra ID 帐户。
我已按照此处的步骤使用 Entra ID 设置身份验证,因此我可以登录
我目前无法获取有效的访问令牌来调用 Azure DevOps 并检索一些数据。
我不断得到
StatusCode: 203, ReasonPhrase: 'Non-Authoritative Information'
如果是 401,我会认为我的应用程序配置有问题。然而,它是 203,所以我怀疑令牌格式可能不正确。返回的令牌是 JWT 格式,而不是通常的 PAT 格式,所以我不确定如何继续。
下面是我的客户端应用程序代码
程序.cs
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using testauthblazor.Client;
using testauthblazor.Client.Services;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
builder.Services.AddHttpClient("testauthblazor.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
// Supply HttpClient instances that include access tokens when making requests to the server project
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("testauthblazor.ServerAPI"));
builder.Services.AddScoped<AzureDevOpsService>();
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add("https://twonline.onmicrosoft.com/xxxx-xxxx-xxxx-xxxx-xxxxxxx/.default");
});
await builder.Build().RunAsync();
测试页.razor
@page "/testpage"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using testauthblazor.Client.Services
@inject AzureDevOpsService DevOpsService
@inject IAccessTokenProvider TokenProvider
<h3>Azure DevOps Projects</h3>
@if (projects == null)
{
<p>Loading...</p>
}
else if (projects.Count == 0)
{
<p>No projects found.</p>
}
else
{
<ul>
@foreach (var project in projects)
{
<li>@project</li>
}
</ul>
}
@code {
private List<string> projects;
protected override async Task OnInitializedAsync()
{
var result = await TokenProvider.RequestAccessToken();
if (result.TryGetToken(out var token))
{
projects = await DevOpsService.GetProjectsAsync(token.Value);
}
}
}
AzureDevOpsService.cs
public class AzureDevOpsService(HttpClient httpClient)
{
private readonly HttpClient _httpClient = httpClient;
public async Task<List<string>> GetProjectsAsync(string accessToken)
{
var request = new HttpRequestMessage(HttpMethod.Get, "https://dev.azure.com/wtwcrb/_apis/projects?api-version=7.1");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var response = await _httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
var projects = JsonDocument.Parse(content).RootElement.GetProperty("value").EnumerateArray()
.Select(p => p.GetProperty("name").GetString()).ToList();
return projects;
}
}
发生错误是因为您在生成访问令牌时使用了错误的范围。验证 Azure DevOps API 的正确范围是
499b84ac-1321-427f-aa17-267ca6975798/.default
确保在您的客户端应用程序中添加
vso.project
DevOps API 权限并征得同意,如下所示:
现在更改客户端应用程序的 Program.cs 文件中的以下代码行:
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add("499b84ac-1321-427f-aa17-267ca6975798/vso.project");
});
当我更改范围值后再次运行项目时,我成功获得了 Azure DevOps 项目列表,如下所示:
参考: