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.