C# 为什么我的AAD保护Azure函数在使用UWP应用程序的访问令牌调用时返回401?
我已经阅读并尝试了很多其他资源,但都没有成功 我有一个UWP应用程序,它调用受AAD保护的HTTP触发Azure函数。我在Azure门户的AAD部分创建了两个应用程序注册。API应用程序注册指定了一个作用域,并且应用程序ID URI为C# 为什么我的AAD保护Azure函数在使用UWP应用程序的访问令牌调用时返回401?,c#,azure,authentication,azure-active-directory,azure-functions,C#,Azure,Authentication,Azure Active Directory,Azure Functions,我已经阅读并尝试了很多其他资源,但都没有成功 我有一个UWP应用程序,它调用受AAD保护的HTTP触发Azure函数。我在Azure门户的AAD部分创建了两个应用程序注册。API应用程序注册指定了一个作用域,并且应用程序ID URI为api://5e6b2b53-...。在“身份验证”刀片上,我设置https://login.microsoftonline.com/common/oauth2/nativeclient作为重定向URI。我已经设置了与UWP应用程序注册的重定向URI相同的值(我不知
api://5e6b2b53-...
。在“身份验证”刀片上,我设置https://login.microsoftonline.com/common/oauth2/nativeclient
作为重定向URI。我已经设置了与UWP应用程序注册的重定向URI相同的值(我不知道是否正确)。我还设定:
在功能应用程序注册。我还为函数应用程序注册设置了以下重定向URI,但我不知道是否需要:
UWP应用程序注册使用我在功能应用程序注册中定义的正确范围。两个应用程序注册都是多租户的。我在UWP应用程序上用于调用受保护Azure函数的代码是:
namespace ClientApplication
{
public partial class MainPage
{
private readonly HttpClient _httpClient;
private const string ClientId = "..."; // Client ID of the UWP app registration
private const string Tenant = "..."; // My Azure tenant ID
private const string Authority = "https://login.microsoftonline.com/" + Tenant;
private readonly string[] _scopes = { "api://5e6b2b53-.../user_impersonation2" };
public MainPage()
{
_httpClient = new HttpClient();
BindingContext = this;
InitializeComponent();
}
private async void Button_OnClicked(object sender, EventArgs e)
{
var app = PublicClientApplicationBuilder.Create(ClientId)
.WithAuthority(Authority)
.WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient")
.WithLogging((level, message, containsPii) =>
{
Debug.WriteLine($"MSAL: {level} {message} ");
}, LogLevel.Warning, false, true)
.Build();
AuthenticationResult result;
var accounts = await app.GetAccountsAsync();
try
{
result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).ExecuteAsync();
}
catch (MsalUiRequiredException)
{
try
{
result = await app.AcquireTokenInteractive(_scopes).ExecuteAsync();
}
catch (Exception exception)
{
Console.WriteLine(exception);
throw;
}
}
if (result == null) return;
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
var response = _httpClient.GetAsync("URL of my HTTP-triggered Azure Function").Result;
var jsonResponseContent = await response.Content.ReadAsStringAsync();
}
}
}
在Azure功能页面上,我设置:
及
其中,发卡机构URL由我的Azure租户ID组成,如下所述:
你能帮我理解为什么我用从身份提供者那里获得的访问令牌调用Azure函数时会得到401吗?这是我获得的访问令牌的重要部分
我做了一些测试,希望能有所帮助,如果我在某些地方误解了,请指出 首先,当我调用
GET时,我创建了一个http触发器函数https://xxx.azurewebsites.net/api/HttpTrigger1?name=asdfg
,我会得到类似于你好asdfg
的响应
然后我通过azure ad启用了身份验证。这意味着我创建了一个新的azure ad应用程序,公开了一个类似这样的api。
在这一步之后,当我调用GET请求时,它会要求我登录,然后我可以得到相同的响应。接下来,我创建了另一个azure ad应用程序,并添加了我刚才公开的api的api权限,通过该应用程序,我可以生成该api范围内的访问令牌,并且通过授权请求头中的该访问令牌,我可以直接访问GET请求
我发现从
https://login.microsoftonline.com/[租户ID]
到
https://login.microsoftonline.com/[租户ID]/v2.0
解决了这个问题。我仍然不明白为什么它不起作用,因为文档说省略了
/v2.0
,我想可能是由于暴露的api导致的错误。我的公开api是在我添加身份验证时自动生成的。你说的“自动生成”是什么意思?我指的是azure ad app中的设置,包括“添加客户端机密”、“公开api”为什么要硬编码访问令牌?它来自哪里?我写了一个演示,所以我从postman生成了访问toke,你在代码中生成访问令牌有困难吗?我找到了解决方案;我提供它作为对这个问题的回答。谢谢你的回答,先生,祝贺你。我还尝试在“Express”中添加身份验证(经典),但没有在“Advance”中添加身份验证,因此我没有像您这样做过很多配置。不管怎样,很好:)谢谢你抽出时间。