stu*_*ilo 5 c# authorization azure-ad-b2c asp.net-core-2.0
将 Authorize 属性与我在 Startup.cs 中定义的策略一起使用时遇到问题。我编辑了我的控制器以手动检查声明。我可以看到包含具有正确范围的范围声明的声明,但是当我手动检查该声明/范围时,它返回为 false。我使用 Azure AD B2C 作为我的身份服务器并成功获得了一个经过验证的令牌。
这是我的 Startup.cs 中的代码:
services.AddAuthorization(options =>
{
var policyRead = new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.RequireClaim("http://schemas.microsoft.com/identity/claims/scope", "vendor.read")
.Build();
options.AddPolicy("VendorRead", policyRead);
var policyWrite = new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.RequireClaim("http://schemas.microsoft.com/identity/claims/scope", "vendor.write")
.Build();
options.AddPolicy("VendorWrite", policyWrite);
});
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwtOptions =>
{
jwtOptions.Authority = $"{Configuration["AzureAdB2C:Instance"]}/{Configuration["AzureAdB2C:TenantId"]}/{Configuration["AzureAdB2C:SignUpSignInPolicyId"]}/v2.0/";
jwtOptions.Audience = Configuration["AzureAdB2C:ClientId"];
jwtOptions.RequireHttpsMetadata = true;
jwtOptions.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = $"{Configuration["AzureAdB2C:Instance"]}/{Configuration["AzureAdB2C:TenantId"]}/v2.0/",
ValidAudience = Configuration["AzureAdB2C:ClientId"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["AzureAdB2C:ClientSecret"]))
};
jwtOptions.Events = new JwtBearerEvents
{
OnAuthenticationFailed = AuthenticationFailed,
OnTokenValidated = TokenValidated
};
});
Run Code Online (Sandbox Code Playgroud)
这是我手动检查声明的控制器代码:
// GET: api/Vendor/5
[HttpGet("{id}")]
public async Task<IActionResult> Get(VendorRequest request)
{
var hasClaim1 = User.HasClaim(c => c.Type == "vendor.read");
var hasClaim2 = User.HasClaim(c => c.Type == "scope");
var hasClaim3 = User.HasClaim(c => c.Type == "scp");
var hasClaim4 = User.HasClaim(c => c.Type == "http://schemas.microsoft.com/identity/claims/scope");
var hasClaim5 = User.HasClaim("http://schemas.microsoft.com/identity/claims/scope", "vendor.read");
var hasClaim7= User.HasClaim("http://schemas.microsoft.com/identity/claims/scope", "vendor.write");
var allowed = await _authorization.AuthorizeAsync(User, "VendorRead");
if (!allowed.Succeeded)
{
return StatusCode(StatusCodes.Status403Forbidden);
}
Run Code Online (Sandbox Code Playgroud)
唯一返回为 true 的 hasClaim 是 hasClaim4。
关于我做错了什么的任何想法?我只是想让 vendor.read 范围现在可以工作。
范围声明是一个以空格分隔的列表,因此RequireClaim()在这种情况下助手将不起作用,但更通用RequireAssertion()。
范围声明示例
"scp": "demo.read demo.write user_impersonation Test-Value"
Run Code Online (Sandbox Code Playgroud)
样本 RequireAssertion()
"scp": "demo.read demo.write user_impersonation Test-Value"
Run Code Online (Sandbox Code Playgroud)
样本 Controller
[Authorize("ScopeCheck")]
public class SecureController : Controller
{
[HttpGet]
public IActionResult Test()
{
return Ok(new { Message = "You are allowed" });
}
}
Run Code Online (Sandbox Code Playgroud)
访问令牌范围(RFC 6749 第 3.3 节)
scope 参数的值表示为以空格分隔、区分大小写的字符串列表。字符串由授权服务器定义。如果该值包含多个以空格分隔的字符串,则它们的顺序无关紧要,每个字符串都会为请求的范围添加一个额外的访问范围
| 归档时间: |
|
| 查看次数: |
5924 次 |
| 最近记录: |