When writing custom code, it might be necessary to call a method that is protected by access control. In some cases, it might be necessary to run this code without access control because this action is considered part of another action that was already checked.
For example, when creating a method that specifically updates a name in the document, this method needs to retrieve the document and update the name. Assuming this method already checks for the update permission on documents, permission for retrieving the document should not be checked again.
There are two ways to run code without access control. The first is through a method, and the second is by using an annotation. These are explained below.
When writing custom code, certain calls to authorized methods can be wrapped in a runWithoutAuthorization
call to
prevent access control checks. This can be done by using the runWithoutAuthorization
method on the
AuthorizationContext
class. This method takes a Callable
as an argument, and runs the code without access control.
class SomeDocumentService(
private val documentService: JsonSchemaDocumentService,
private val authorizationService: AuthorizationService
) {
fun updateName(name: String, documentId: String) {
// We wrap authorized code in a runWithoutAuthorization call to prevent access control checks
val document = runWithoutAuthorization {
// calling this method would normally require the JsonSchemaDocument VIEW permission
documentService.get(documentId)
}
// update the document
...
// Do a permission check to protect this method from unauthorized access
// In this case we're checking for the custom JsonSchemaDocument UPDATE-NAME permission
authorizationService.requirePermission(
EntityAuthorizationRequest(
JsonSchemaDocument::class.java,
Action("UPDATE-NAME"),
document
)
)
}
}
Any calls to methods that are annotated with @RunWithoutAuthorization
will not be checked by the access control layer.
This is accomplished by using Spring AOP to intercept the method call and run the method without access control. This
means this will not work for methods that are called from within the same class, as the annotation is not intercepted
when called from within the same class.
class SomeDocumentService(
private val documentService: JsonSchemaDocumentService,
) {
// Any calls to this method disable access control checks just for this method
@RunWithoutAuthorization
fun updateName(name: String, documentId: String) {
// Retrieve the document. Calling this method would normally require the JsonSchemaDocument VIEW permission
val document = documentService.get(documentId)
// Update the document
...
}
}
The downside to this approach is that it disables access control for the entire method, which means the method is
insecure and should be used with caution. It is usually better to use the AuthorizationContext.runWithoutAuthorization
method instead.