Authorization Failed Reasons
Note
Reasons with AspNetCore will only work on .NET 6 or higher.
Reasons also only work when using the embedded OPA.
It is possible to use OPADotNet to output reasons to the end-user on why they were unable to be authorized.
This is done first by adding reason text inside of the policy:
package reason_test
# REASON: You must be authorized
allow {
has_scope_test
}
# REASON: You must have scope test
has_scope_test {
input.subject.claims.scopes[_] = "test"
}
When adding OPA in the startup class, you must also add:
services.AddOpa(opt => {
...
opt.UseReasons();
...
});
The reason is then given in under the failure object for an authorization check:
var authResult = await _authorizationService.AuthorizeAsync(HttpContext.User, "read");
if (!authResult.Succeeded)
{
// Get the first failure reason message if there is only one requirement (OPA requirement).
return Unauthorized(authResult.Failure?.FailureReasons.FirstOrDefault()?.Message);
}
The output from the policy above if the user does not have scope “test” would then be:
You must be authorized
* You must have scope test
Accessing parameters
Formatting the reason message with parameters is possible as shown in the following example:
allow {
must_have_scope("test")
}
# REASON: You must have scope: {0}
must_have_scope(scope_name) {
...
}
Which would be translated to: “You must have scope: test”
Limitations
Reasons will not output correctly for blocks that uses “unknown” data variables. Say if input.subject.name == data.unknown.owner would fail, a reason would not be given correctly.
Reasons only work with the embedded OPA module, this is because it requires the line numbers in the explanations to locate the correct reasons above a block.
Failure reasons was added in .NET 6 which means that it is only possible to get the output reason in .NET 6.
Performance impacts
Using reasons will imply a small performance impact, since for each policy evaluation the explanation must be extracted from the embedded OPA and interpretted to create the final reason message.