Azure active directory 使用Azure Active directory访问Azure函数时Blazor客户端获取CORS错误
我已经尝试部署我的Blazor PWA两天了,到目前为止没有任何成功,如果有人知道我做错了什么,我将非常感激。 你好 我可以自己解决大部分问题,但我现在被困在使用AAD的CORS问题上 以下是我的项目设置:Azure active directory 使用Azure Active directory访问Azure函数时Blazor客户端获取CORS错误,azure-active-directory,blazor,blazor-client-side,azure-function-app,Azure Active Directory,Blazor,Blazor Client Side,Azure Function App,我已经尝试部署我的Blazor PWA两天了,到目前为止没有任何成功,如果有人知道我做错了什么,我将非常感激。 你好 我可以自己解决大部分问题,但我现在被困在使用AAD的CORS问题上 以下是我的项目设置: Blazor webassembly客户端托管在静态网站存储(works)上 太好了),净5 AzureFunctions连接到Azure Sql Server数据库(非常有效 在Blazor中使用匿名身份验证) 我要使用Azure Active Directory对用户进行身份验证。 (
- Blazor webassembly客户端托管在静态网站存储(works)上 太好了),净5
- AzureFunctions连接到Azure Sql Server数据库(非常有效 在Blazor中使用匿名身份验证)
- 我要使用Azure Active Directory对用户进行身份验证。 (保护blazor应用程序和功能)
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication); //contains clientId, Authority
options.ProviderOptions.DefaultAccessTokenScopes.Add("https://graph.microsoft.com/User.Read");
options.ProviderOptions.LoginMode = "redirect";
});
这也很好,我可以登录,授权查看工程的预期
问题是当我尝试使用«使用Azure Active Directory登录»验证Azure函数时,
我尝试了express和advanced配置(使用clientId、tenantId),但当我
在'https://login.windows.net/tenantid/oauth2/authorize ... (从'https://myfunctionstorage.azurewebsites.net/api/client/list“)来自源“https://****9.web.core.windows.net”已被CORS策略阻止:请求的资源上不存在“访问控制允许源”标头。如果不透明响应满足您的需要,请将请求的模式设置为“no cors”,以获取禁用cors的资源
我当然在Azure功能配置中为Blazor客户端地址启用了CORS,但问题似乎与登录windows uri有关
此外,如果我在应用程序注册中启用令牌id隐式流,并在浏览器中访问登录url,那么它就可以正常工作
到目前为止,我能找到的所有例子都是关于MSAL1.0和使用隐式流而不是SPA的应用程序注册的,所以它没有帮助
谢谢你的时间和帮助
更新:
从昨天开始,我做了更多的研究,我认为这可能与我的HTTPClient有关,目前我使用的是基本的(只有一个基本地址)
但我在一些示例中看到,当使用AAD使用客户端时,它需要更多参数,例如:
builder.Services.AddHttpClient("companiesAPI", cl => { cl.BaseAddress = new Uri("https://localhost:5001/api/"); }) .AddHttpMessageHandler(sp => { var handler = sp.GetService<AuthorizationMessageHandler>() .ConfigureHandler( authorizedUrls: new[] { "https://localhost:5001" }, scopes: new[] { "companyApi" } ); return handler; });
builder.Services.AddHttpClient(“companiesAPI”,cl=>{cl.BaseAddress=newURI(“https://localhost:5001/api/AddHttpMessageHandler(sp=>{var handler=sp.GetService().ConfigureHandler(authorizedURL:new[]{https://localhost:5001},作用域:new[]{“companyApi”};返回处理程序;});
需要授权MessageHandler吗?
此外,我还看到一些关于需要使用«use_impersonation»范围的参考资料
在使用msal2/SPA应用程序注册时,是否也需要这些更改(在HttpClient和use_模拟范围上)
谢谢如果要调用Blazor webassembly客户端中Azure AD投影的Azure函数,请参考以下步骤 如果您想在angular应用程序中调用Azure AD投影的Azure函数,请参考以下代码
- 创建Azure广告应用程序以保护功能
- 注册Azure广告应用程序。完成此操作后,请复制应用程序(客户端)ID和目录(租户)ID
- 配置重定向URI。选择Web并键入
- 创建客户端机密
- 在应用程序服务应用程序中启用Azure Active Directory
- 在Azure功能中配置CORS策略
- 创建客户端广告应用程序以访问功能
- 注册申请
- 启用隐式授权流
- 配置API权限。让您的客户端应用程序具有访问该功能的权限
- 代码
AuthorizationMessageHandler
类@page”/fetchdata
@使用Microsoft.AspNetCore.Components.WebAssembly.Authentication
@注入HttpClient Http
调用Azure函数
此组件演示如何从服务器获取数据
结果:@预测
调用函数
@代码{
私人字符串预测;
受保护的异步任务CallFun()
{
预测=等待Http.GetStringAsync(“api/Http”);
}
}
您是否查看了“应用程序注册”中配置的重定向url?另外,您是否将它们定义为SPA?谢谢您的回答,是的,我的本地主机和部署url都在重定向url中注册,并且它们被定义为SPA。由于我能够从web客户端登录并从浏览器运行函数(登录后),我敢打赌问题在于客户端和函数API之间的通信。@ChristianMeurrens您是否在Azure函数中配置了CORS:?在函数中配置CORS无助于@JimXu。问题的原因是函数试图进行交互式身份验证,这是错误的,因为它是一个API。您需要检查访问令牌是否正确连接,在中检查令牌中的声明是否符合函数的预期。@Juunas我期待类似的内容,我将深入研究,谢谢。请随意转载作为答案,以便我可以验证。如果它对您有用,您可以吗?
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
public class CustomAuthorizationMessageHandler : AuthorizationMessageHandler
{
public CustomAuthorizationMessageHandler(IAccessTokenProvider provider,
NavigationManager navigationManager)
: base(provider, navigationManager)
{
ConfigureHandler(
authorizedUrls: new[] { "<your function app url>" },
scopes: new[] { "<the function app API scope your define>" });
}
}
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
// register CustomAuthorizationMessageHandler
builder.Services.AddScoped<CustomAuthorizationMessageHandler>();
// configure httpclient
// call the following code please add packageMicrosoft.Extensions.Http 3.1.0
builder.Services.AddHttpClient("ServerAPI", client =>
client.BaseAddress = new Uri("<your function app url>"))
.AddHttpMessageHandler<CustomAuthorizationMessageHandler>();
// register the httpclient
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
.CreateClient("ServerAPI"));
// configure Azure AD auth
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add("<the function app API scope your define>");
});
await builder.Build().RunAsync();
}
@page "/fetchdata"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@inject HttpClient Http
<h1>Call Azure Function</h1>
<p>This component demonstrates fetching data from the server.</p>
<p>Result: @forecasts</p>
<button class="btn btn-primary" @onclick="CallFun">Call Function</button>
@code {
private string forecasts;
protected async Task CallFun()
{
forecasts = await Http.GetStringAsync("api/http");
}
}