### Description

`TransportGrantAction` currently provides an `executeWithGrantAuthentication` method which sub-classes can leverage. Instead of requiring sub-classes to invoke this method directly, we instead can move it into the `doExecute` method of `TransportGrantAction`, and allow inheritors to specify their own handler for grant authentication, something along the lines of: 

```
class TransportGrantAction {

    final void doExecute(...) {
        // executeWithGrantAuthentication can furthermore be inlined as part of this refactor
        executeWithGrantAuthentication(request, ActionListener.wrap(
            authentication -> { doSomethingWithAuthentication(...) }
        ));
    }

    abstract doSomethingWithAuthentication(...);
}
```

This reduces boilerplate and establishes a clearer contract for sub-classes of `TransportGrantAction`.
x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/action/apikey/TransportBaseUpdateApiKeyAction.java
HandledTransportAction<Request, Response> {
    private final SecurityContext securityContext;
    private final ApiKeyUserRoleDescriptorResolver resolver;
    protected TransportBaseUpdateApiKeyAction(
        final String actionName,
        final TransportService transportService,
        final ActionFilters actionFilters,
        final Writeable.Reader<Request> requestReader,
        final SecurityContext context,
        final CompositeRolesStore rolesStore,
        final NamedXContentRegistry xContentRegistry
    ) {
        super(actionName, transportService, actionFilters, requestReader);
        this.securityContext = context;
        this.resolver = new ApiKeyUserRoleDescriptorResolver(rolesStore, xContentRegistry);