如果 appsettings.json 中的字段 "allowed" 为真,我可以允许未经授权的用户访问控制器吗?
Can I allow for unauthorized user to have access to controller if the field "allowed" in appsettings.json is true?
正如标题所说,我尽量让控制器区分两种状态。
- 如果 appsettings 中的“允许”字段为真,则允许未经授权的用户访问控制器。
- 如果“allowed”为 false,则只允许授权用户访问。
但我不太明白如何使用策略来实现它。
我可以通过某种方式将布尔值传递给授权属性吗?
编辑
控制器
[Authorize(Policy ="Unauthenticated")] // to pass here some additional argument
public string GetController();
在Policy based Authorization Handler方法中,可以通过Configuration provider获取allowed
值,然后根据该值进行策略授权或忽略授权。
例如,基于this article,我创建了一个MinimumAgeHandler:
public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement>
{
private readonly UserManager<ApplicationUser> _userManager; //used to get the current user information.
private readonly IConfiguration _configuration;
public MinimumAgeHandler(UserManager<ApplicationUser> manager, IConfiguration configuration)
{
_userManager = manager;
_configuration = configuration;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MinimumAgeRequirement requirement)
{
if (context.User == null)
{
return Task.CompletedTask;
}
if (!context.User.HasClaim(c => c.Type == ClaimTypes.Name))
{
//TODO: Use the following if targeting a version of
//.NET Framework older than 4.6:
// return Task.FromResult(0);
return Task.CompletedTask;
}
//get the Allowed value from the appsettings.json.
var isAllowed = _configuration["Allowed"];
//
if (isAllowed != "True")
{
//policy authorization handler
var user = context.User;
var age = _userManager.GetUserAsync(user).Result.Age;
if (age >= requirement.MinimumAge)
{
context.Succeed(requirement);
}
}
else
{
//ignore the policy authorization handler.
context.Succeed(requirement);
}
//TODO: Use the following if targeting a version of
//.NET Framework older than 4.6:
// return Task.FromResult(0);
return Task.CompletedTask;
}
}
和 MinimumAgeRequirement:
public class MinimumAgeRequirement : IAuthorizationRequirement
{
public int MinimumAge { get; }
public MinimumAgeRequirement(int minimumAge)
{
MinimumAge = minimumAge;
}
}
然后,注册授权:
services.AddAuthorization(options =>
{
options.AddPolicy("AtLeast21", policy =>
policy.Requirements.Add(new MinimumAgeRequirement(21)));
});
services.AddScoped<IAuthorizationHandler, MinimumAgeHandler>();
在 appsettings.json 文件中添加 "Allowed": true,
。
最后,在action方法中添加Authorize属性:
[Authorize(Policy = "AtLeast21")]
public IActionResult Index()
{
}
使用上面的示例代码,用户登录后,如果Allowed
是True
,将忽略MinimumAge验证。
正如标题所说,我尽量让控制器区分两种状态。
- 如果 appsettings 中的“允许”字段为真,则允许未经授权的用户访问控制器。
- 如果“allowed”为 false,则只允许授权用户访问。
但我不太明白如何使用策略来实现它。 我可以通过某种方式将布尔值传递给授权属性吗?
编辑
控制器
[Authorize(Policy ="Unauthenticated")] // to pass here some additional argument
public string GetController();
在Policy based Authorization Handler方法中,可以通过Configuration provider获取allowed
值,然后根据该值进行策略授权或忽略授权。
例如,基于this article,我创建了一个MinimumAgeHandler:
public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement>
{
private readonly UserManager<ApplicationUser> _userManager; //used to get the current user information.
private readonly IConfiguration _configuration;
public MinimumAgeHandler(UserManager<ApplicationUser> manager, IConfiguration configuration)
{
_userManager = manager;
_configuration = configuration;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MinimumAgeRequirement requirement)
{
if (context.User == null)
{
return Task.CompletedTask;
}
if (!context.User.HasClaim(c => c.Type == ClaimTypes.Name))
{
//TODO: Use the following if targeting a version of
//.NET Framework older than 4.6:
// return Task.FromResult(0);
return Task.CompletedTask;
}
//get the Allowed value from the appsettings.json.
var isAllowed = _configuration["Allowed"];
//
if (isAllowed != "True")
{
//policy authorization handler
var user = context.User;
var age = _userManager.GetUserAsync(user).Result.Age;
if (age >= requirement.MinimumAge)
{
context.Succeed(requirement);
}
}
else
{
//ignore the policy authorization handler.
context.Succeed(requirement);
}
//TODO: Use the following if targeting a version of
//.NET Framework older than 4.6:
// return Task.FromResult(0);
return Task.CompletedTask;
}
}
和 MinimumAgeRequirement:
public class MinimumAgeRequirement : IAuthorizationRequirement
{
public int MinimumAge { get; }
public MinimumAgeRequirement(int minimumAge)
{
MinimumAge = minimumAge;
}
}
然后,注册授权:
services.AddAuthorization(options =>
{
options.AddPolicy("AtLeast21", policy =>
policy.Requirements.Add(new MinimumAgeRequirement(21)));
});
services.AddScoped<IAuthorizationHandler, MinimumAgeHandler>();
在 appsettings.json 文件中添加 "Allowed": true,
。
最后,在action方法中添加Authorize属性:
[Authorize(Policy = "AtLeast21")]
public IActionResult Index()
{
}
使用上面的示例代码,用户登录后,如果Allowed
是True
,将忽略MinimumAge验证。