我见过很多相同或类似的问题,并尝试了他们所有的答案(如果有的话),但这些都不适合我。
我在用着这个例子 https://github.com/Azure-Samples/ms-identity-javascript-angular-spa-aspnetcore-webapi来自微软的Github帐户作为我的项目库。
它非常适合仅登录的用户。
该项目有 1 个 WebApi、1 个 Angular App。
然后我按照这个微软的例子 https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/2-WebApp-graph-user/2-1-Call-MSGraph添加调用 Graph API 的代码。
这是控制器代码:
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class BillsController : ControllerBase
{
static readonly string[] scopeRequiredByApi = new string[] { "access_as_user" };
readonly ITokenAcquisition tokenAcquisition;
readonly WebOptions webOptions;
public BillsController(ITokenAcquisition tokenAcquisition,
IOptions<WebOptions> webOptionValue)
{
this.tokenAcquisition = tokenAcquisition;
this.webOptions = webOptionValue.Value;
}
[HttpGet]
[AuthorizeForScopes(Scopes = new[] { Constants.ScopeUserRead, Constants.ScopeMailRead })]
public async Task<IActionResult> Profile()
{
HttpContext.VerifyUserHasAnyAcceptedScope(scopeRequiredByApi);
var subject = string.Empty;
try
{
// Initialize the GraphServiceClient.
Graph::GraphServiceClient graphClient = GetGraphServiceClient(new[] { Constants.ScopeUserRead, Constants.ScopeMailRead });
var me = await graphClient.Me.Request().GetAsync();
// Get user photo
var messages = await graphClient.Me.MailFolders.Inbox.Messages.Request().GetAsync();
subject = messages.First().Subject;
return Ok(subject);
}
catch (System.Exception ex)
{
throw ex;
}
}
private Graph::GraphServiceClient GetGraphServiceClient(string[] scopes)
{
return GraphServiceClientFactory.GetAuthenticatedGraphClient(async () =>
{
string result = await tokenAcquisition.GetAccessTokenForUserAsync(scopes);
return result;
}, webOptions.GraphApiUrl);
}
}
对于 Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// Setting configuration for protected web api
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddProtectedWebApi(Configuration);
services.AddWebAppCallsProtectedWebApi(Configuration, new string[] { Constants.ScopeUserRead, Constants.ScopeMailRead })
.AddInMemoryTokenCaches();
services.AddOptions();
services.AddGraphService(Configuration);
// Creating policies that wraps the authorization requirements
services.AddAuthorization();
services.AddDbContext<TodoContext>(opt => opt.UseInMemoryDatabase("TodoList"));
services.AddControllers();
// Allowing CORS for all domains and methods for the purpose of sample
services.AddCors(o => o.AddPolicy("default", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
// Since IdentityModel version 5.2.1 (or since Microsoft.AspNetCore.Authentication.JwtBearer version 2.2.0),
// Personal Identifiable Information is not written to the logs by default, to be compliant with GDPR.
// For debugging/development purposes, one can enable additional detail in exceptions by setting IdentityModelEventSource.ShowPII to true.
// Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseExceptionHandler("/error");
app.UseCors("default");
app.UseHttpsRedirection();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
在 Angular 应用程序上,我添加了一个按钮来调用此 Profile() 控制器操作。
todo-view.component.ts
getEmails(): void {
this.service.getEmails().subscribe({
next: (emails: any) => {
alert(emails);
},
error: (err: any) => {
console.log("error happened~!");
console.log(err);
}
});
}
todo-view.component.html
<button (click)="getEmails();">Get Emails</button>
我将以下代码添加到 Startup.cs 中并删除了 AddWebAppCallsProtectedWebApi。
services.AddProtectedWebApiCallsProtectedWebApi(配置).AddInMemoryTokenCaches();
现在它向我抛出了不同的错误消息: