Using OAuth2 on non-REST endpoints I have a custom module which includes a ControllerBase. The controller has a content() function that returns a JsonResponse(). The code for this function returns a complete list of a certain entity type.

I've tried using REST for this, but the entity structure is decently complicated and contains several field collections. By default, REST will just include the ID of a field collection as part of its presentation of this entity, so I've written a FieldFormatter plugin that replaces the field collection ID with a JSON object of its contents. Unfortunately, that requires significant overhead when returning an entire list of the entity type via REST, and takes 40 seconds to load. However, OAuth2 works fine with it.

Alternatively, my existing custom connector takes approximately two to three seconds to load, as it is a single sanitized SQL statement that outputs its results as a JSON. However, I only have Basic Auth working with this, attempting OAuth2 returns a 403 error. I am using the simple_oauth module.

I'm wondering if there is a way to:


A) improve the response time on the REST endpoint to be as good as the custom controller

or
B) use OAuth2 with the custom controller. I've been looking for instructions on this but every OAuth2 resource I've come across so far assumes I'm using a REST endpoint.


edit to update: The REST endpoint is caching, which seems good as it's now loading much faster after the initial fetch, but (as is expected behaviour) the cache is flushed along with all other caches which is something we need to do fairly often, meaning the next person to access the endpoint will see an unusually slow response time. This isn't ideal, and I'd like to still investigate the custom controller I made, however adding _auth: ['oauth2'] to the YAML file is not fixing the 403 error.

2nd edit to update: This is my YAML for the custom controller, which is also not working:

connector.modulename:
  path: '/connector/modulename'
  defaults:
    _controller: \Drupal\connector\Controller\ModuleNameConnectorController::content
  requirements:
    _permission: 'view modulename entity'
  options:
    _auth: ['simple_oauth']


It does not work with _auth: ['simple_oauth'] or _auth: ['oauth2'] (403 error), but does work with _auth: ['basic_auth']. I'm using Postman to connect with a fresh (~30 sec, expiry 5 min) token. The same oauth2 token works for the REST connector. The error message I'm getting in my admin logs states: 

League\OAuth2\Server\Exception\OAuthServerException: The resource owner or authorization server denied the request. in League\OAuth2\Server\Exception\OAuthServerException::accessDenied() (line 173 of C:\directory_to_my_site\vendor\league\oauth2-server\src\Exception\OAuthServerException.php).


and also issues a PHP warning stating that access was denied to Guest (not verified).
A) improve the response time on the REST endpoint to be as good as the
  custom controller


For the REST endpoint, you can use $response-&gt;addCacheableDependency() check this block for example:
https://blog.dcycle.com/blog/2018-01-24/caching-drupal-8-rest-resource/
https://spinningcode.org/2017/05/cached-json-responses-in-drupal-8/

Make sure to add cache context and cache tags, carefully.


  B) use OAuth2 with the custom controller. I've been looking for
  instructions on this but every OAuth2 resource I've come across so far
  assumes I'm using a REST endpoint.


Check the example from "simple_oauth_extras" sub module of "simple_oauth"
https://git.drupalcode.org/project/simple_oauth/blob/8.x-3.x/simple_oauth_extras/simple_oauth_extras.routing.yml#L22

Controller is:
https://git.drupalcode.org/project/simple_oauth/blob/8.x-3.x/simple_oauth_extras/src/Controller/DebugController.php#L39