I want to authorize an action controller could access by multiple policies.
.e.g:
[Authorize([Policies.ManageAllCalculationPolicy,Policies.ManageAllPriceListPolicy]]
public async Task<IActionResult> Get(int id){}
Thank a lot.
I want to authorize an action controller could access by multiple policies.
.e.g:
[Authorize([Policies.ManageAllCalculationPolicy,Policies.ManageAllPriceListPolicy]]
public async Task<IActionResult> Get(int id){}
Thank a lot.
For multiple policies, you could implement your own AuthorizeAttribute.
AuthorizeMultiplePolicyAttribute
public class AuthorizeMultiplePolicyAttribute:TypeFilterAttribute
{
public AuthorizeMultiplePolicyAttribute(string policies,bool IsAll):base(typeof(AuthorizeMultiplePolicyFilter))
{
Arguments = new object[] { policies,IsAll};
}
}
AuthorizeMultiplePolicyFilter
public class AuthorizeMultiplePolicyFilter: IAsyncAuthorizationFilter
{
private readonly IAuthorizationService _authorization;
public string _policies { get; private set; }
public bool _isAll { get; set; }
public AuthorizeMultiplePolicyFilter(string policies, bool IsAll,IAuthorizationService authorization)
{
_policies = policies;
_authorization = authorization;
_isAll = IsAll;
}
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
var policys = _policies.Split(";").ToList();
if (_isAll)
{
foreach (var policy in policys)
{
var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, policy);
if (!authorized.Succeeded)
{
context.Result = new ForbidResult();
return;
}
}
}
else
{
foreach (var policy in policys)
{
var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, policy);
if (authorized.Succeeded)
{
return;
}
}
context.Result = new ForbidResult();
return;
}
}
}
Add Policy you want on Startup
services.AddAuthorization(options =>
{
options.AddPolicy("ManageAllCalculationPolicy", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c => c.Type == "BadgeId")));
options.AddPolicy("ManageAllPriceListPolicy", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c => c.Type == "aaaa")));
});
Authorization based on one of the policies
[AuthorizeMultiplePolicy("ManageAllCalculationPolicy;ManageAllPriceListPolicy", false)]
Authorization based on all policies
[AuthorizeMultiplePolicy("ManageAllCalculationPolicy;ManageAllPriceListPolicy", true)]
No, you cannot add multiple policies as a list with condition or. I think NetCore does not support that.
Try to create a new policy.
services.AddAuthorization(options =>
{
options.AddPolicy("BadgeEntry", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c =>
(c.Type == ClaimTypes.BadgeId ||
c.Type == ClaimTypes.TemporaryBadgeId) &&
c.Issuer == "https://microsoftsecurity")));
});
Authorize attribute for ages.Worked like a charm!!
Here is my part of code in Startup.ConfigureServices
services.AddAuthorization(config =>
{
config.AddPolicy(Policies.Admin, Policies.AdminPolicy());
config.AddPolicy(Policies.Register, Policies.RegistradorPolicy());
});
And, for example.. policies are:
public class Policies
{
public const string Admin = 'Admin';
public const string Register = 'Register';
public static AuthorizationPolicy AdminPolicy()
{
return new AuthorizationPolicyBuilder().RequireAuthenticatedUser().RequireRole(Admin).Build();
}
public static AuthorizationPolicy RegisterPolicy()
{
return new AuthorizationPolicyBuilder().RequireAuthenticatedUser().RequireRole(Register).Build();
}
}
Then in controllers..
[HttpGet]
[AuthorizeMultiplePolicy(Policies.Admin + ";" + Policies.Register, false)]
public ActionResult<IEnumerable<Accion>> GetAll(){
}
You can add multiple policies like that
services.AddAuthorization(options =>
{
options.AddPolicy("BadgeEntry", PolicyClaimCheck.Any, new string[2] { "VT102","RS102" });
options.AddPolicy("Notification", PolicyClaimCheck.All, new string[2] { "XTX101","NT102" });
});
If it is enough to have one, you should use PolicyClaimCheck.Any or If it must have all, you should use PolicyClaimCheck.All
PolciyClaimCheck is not available in .net core 3.1