Let’s say you have the following authorization policy defined in the Configure method of your ASP.NET Core’s Startup class.
.AddAuthorization(options =>
{
options.AddPolicy("IsLucky", builder =>
{
var random = new Random();
builder.RequireAssertion(_ => random.Next(1, 100) < 75);
});
})
This policy will grant access about ¾ of the time. It is easy to apply the policy to a controller or Razor page using the Authorize attribute.
[Authorize(Policy = "IsLucky")]
public class SecretsModel : PageModel
{
// ...
}
But, what if you want to imperatively check the policy? For example, when building a navigation menu, you want to know if the user will be able to perform a given action or reach a specific resource before displaying links and command buttons in the UI. In this scenario, ask for an IAuthorizationService type object in any controller or Razor page. The auth service combines a claims principal and a policy name to let you know if the user authorization check succeeds.
For example, in the page model for a Razor page:
public class SecretsModel : PageModel
{
public bool IsLucky { get; set; }
private readonly IAuthorizationService authorization;
public SecretsModel(IAuthorizationService authorization)
{
this.authorization = authorization;
}
public async Task OnGet()
{
var result = await authorization.AuthorizeAsync(User, "IsLucky");
IsLucky = result.Succeeded;
}
}
And then in the page itself:
@if(Model.IsLucky)
{
<div>You got lucky!</div>
}
else
{
<div>No luck for you :(</div>
}
Of course, having an authorization policy that uses a a random number generator is weird, but I'm hoping to work it into a "random access" policy joke someday.
OdeToCode by K. Scott Allen