各位早上好,
我正在实现 Microsoft 身份验证,该部分进展顺利,问题是当我获取用户 access_token 时,该令牌不包含我在 Azure 应用程序中选择的请求权限。在下图中,您可以看到我在 Azure 应用程序中请求的权限。
这是我的 Startup.cs 文件中请求 access_token 的代码。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(options =>
{
Configuration.Bind("AzureAd", options);
options.Events.OnTokenValidated = async context =>
{
var accessToken = context.SecurityToken as JwtSecurityToken;
if (accessToken != null)
{
var claimsIdentity = context.Principal.Identity as ClaimsIdentity;
if (claimsIdentity != null)
{
claimsIdentity.AddClaim(new Claim("access_token", accessToken.RawData));
}
}
};
})
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
services.AddMvc(option =>
{
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
option.Filters.Add(new AuthorizeFilter(policy));
}).AddMicrosoftIdentityUI();
}
这在我的 appsettings.json 的代码中
"AzureAD": {
"Instance": "https://login.microsoftonline.com",
"TenantID": "common",
"ClientID": "916xxxxxx-xx-3f7",
"ClientSecret": "xxxx",
"CallbackUrl": "./signin-oidc",
"SigoutcallbackUrl": "./signout-oidc"
}
我还解码了我的令牌,并且我在 Azure 应用程序中请求的权限(图 1)不在我获得的令牌中。
我缺少什么?
您从
OnTokenValidated
获得的令牌是ID令牌,而不是访问令牌,这就是为什么您无法获得您请求的权限。同时,当我们需要生成包含所需范围(您在AAD中添加的权限)的访问令牌时,我们需要在获取令牌时定义范围。您可以查看 Azure AD 中的常用流程,它们都需要“scope”参数。
当我们需要在asp.net core mvc应用程序中获取访问令牌时,我们可以集成相关库。我们可以有下面的代码。
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(options =>
{
builder.Configuration.Bind("AzureAd", options);
}).EnableTokenAcquisitionToCallDownstreamApi(new string[] { "user.read", "Calendars.ReadWrite" })
.AddInMemoryTokenCaches();
然后在具有
Authorize
属性的控制器中,我们可以注入 ITokenAcquisition
并使用它来生成访问令牌。
private readonly ITokenAcquisition _tokenAcquisition;
public HomeController(ITokenAcquisition tokenAcquisition)
{
_tokenAcquisition = tokenAcquisition;
}
public async Task<IActionResult> IndexAsync()
{
var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new string[] { "User.Read" });
return View();
}
如果不提前登录会出现下面的错误,如果我们登录成功,该服务将为我们生成访问令牌。