[我认为我的主要问题是我应该使用哪种身份验证流程-代表授权还是隐式授权流程?但是,我在Startup.cs
中设置的身份验证和授权可能是错误的,并且我已经离开了,如果可以的话,我们深表歉意。
我在Azure中已有一个Angular SPA,并且也在Azure中运行了Net Framework API。
Web API已被移植到Net Core 3.1。
在我们的Azure目录中,我有两个注册的应用程序。一个用于API,另一个用于SPA。我已在WEB API中的授权客户端下添加了SPA客户端ID。
值得注意的是,App服务实际上是在不同的控制器中运行的(我认为这很好,但只是提及)
这是Azure AD中的相关身份验证/授权设置。
private void ConfigureAzureAD(IServiceCollection services, IMvcBuilder mvcBuilder)
{
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
options.Authority = options.Authority + "/v2.0/";
options.TokenValidationParameters.ValidateIssuer = true;
});
mvcBuilder.AddMvcOptions(options =>
{
var policy = new AuthorizationPolicyBuilder().
RequireAuthenticatedUser().
Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).
SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseResponseCaching();
}
app.UseStaticFiles();
app.UseCors(CORS_POLICY);
if (UseAzureAD)
{
app.UseHttpsRedirection();
}
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthorization();
app.UseAuthentication();
app.UseMvc();
}
我可以直接成功使用API并进行身份验证。
SPA正在使用Angular ADAL。如果我正确阅读的内容将不适用于Microsoft Identity V2端点。 -尽管我仍然无法理解最终的身份验证流程(我认为这是我的主要问题),但我们仍然需要升级到MSAL。
[当前,如果我访问SPA,它将仅使用当前的ADAL Config进行身份验证,但是当它访问API时,将使用ID令牌重定向到https://login.microsoftonline.com/{TenantId}/oauth2/v2.0/authorize?
。
它挂在重定向上,并且它们是CORS错误,因为原点为空。我知道这是预期的,因为SPA配置不正确。
API确实会调用MS Graph API来为用户获取组(但是使用客户端ID和客户端机密来获取访问令牌以调用MS Graph),所以我认为这不需要使用On -代表流量(我确实看到了这篇文章Authenticating against Microsoft Graph with SPA and then using token in Web API)?
我已经看过本示例https://github.com/Azure-Samples/ms-identity-javascript-angular-spa-aspnetcore-webapi的隐式授权流程。
我在该示例中确实注意到,身份验证方案为JwtBearerDefualts
,因为ID令牌是JWT,这很有意义,所以我的问题就成了我的API启动配置。
这里是在API中调用MS Graph的位,可能是最好地回答我应该使用的2个流中的哪一个(再次获得具有客户端密码的访问令牌)。
private async Task<IReadOnlyCollection<string>> LoadReportGroupsCurrentUserCanRead()
{
var objectID = claimsPrincipal
.Claims
.FirstOrDefault(c => c.Type == "http://schemas.microsoft.com/identity/claims/objectidentifier")
?.Value;
var graphServiceClient = await GetGraphServiceClient();
var groups = await graphServiceClient
.Groups
.Request()
.GetAsync();
var memberGroups = await graphServiceClient
.Users[objectID]
.GetMemberGroups(true)
.Request()
.PostAsync();
return memberGroups.Select(mg => groups.SingleOrDefault(g => g.Id == mg))
.Where(g => g?.DisplayName?.EndsWith(" Report Group", StringComparison.InvariantCultureIgnoreCase) == true)
.Select(g => g.Description)
.Where(name => !string.IsNullOrWhiteSpace(name))
.ToArray();
}
private async Task<GraphServiceClient> GetGraphServiceClient()
{
string authority = new Uri(microsoftLogin, tenantID).AbsoluteUri;
var authenticationContext = new AuthenticationContext(authority);
var clientCredential = new ClientCredential(clientID, clientSecret);
var authenticationResult = await authenticationContext.AcquireTokenAsync("https://graph.microsoft.com", clientCredential);
var authProvider = new DelegateAuthenticationProvider(requestMessage =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", authenticationResult.AccessToken);
return Task.CompletedTask;
});
return new GraphServiceClient(authProvider);
}
最后,我认为我们的SPA使用的是不支持Angular MSAL的Angular版本。我可以只使用Vanilla MSAL JS(不认为我们现在没有时间升级Angular)吗?
您应该使用implicit flow和msal-angular。它支持Angular从4到9。此外,除非没有其他选择,否则我不建议在Angular中使用香草库。
不赞成使用ADAL,它不支持融合的应用程序模型(工作+个人帐户,因此您需要转到MSAL。
跟随Create web APIs with ASP.NET Core和Migrate from ASP.NET Core 2.2 to 3.0删除这样的代码:
mvcBuilder.AddMvcOptions(options =>
{
var policy = new AuthorizationPolicyBuilder().
RequireAuthenticatedUser().
Build();
options.Filters.Add(new AuthorizeFilter(policy));
})
而是改为根据Controller and decorate them with ApiController attribute作为控制器的基础。
还有这个,因为它是.NET 3.1:
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
您的MS Graph身份验证正在使用client credentials进行身份验证,这是当前应用程序体系结构的一种通用方法。如果您没有添加太多highly privileged permissions,则应该没问题。