Support bearer token authorization method for introspection endpoint
Environment
- lua-resty-openidc version (e.g. 1.7.0)
- OpenID Connect provider (e.g. Keycloak, Azure AD)
Expected behaviour
In simple version:
- Config:
opts.token_endpoint_auth_method = "bearer_token" - With above config, introspection endpoint request headers will be built like this:
headers.Authorization ="Bearer " .. access_token - Make the request...
Actual behaviour
Now the project only supports authorization by client_secret_basic, client_secret_post, private_key_jwt, client_secret_jwt (by checking auth variable)
Reason
As RFC7662-section 2.1 said:
the endpoint MUST also require some form of authorization to access this endpoint, such as client authentication as described in OAuth 2.0 [RFC6749] or a separate OAuth 2.0 access token such as the bearer token described in OAuth 2.0 Bearer Token Usage [RFC6750]
So resource server could use a separate OAuth 2.0 access token to authorize itself when making introspection request. The following lines in RFC7662 also show the example of request using bearer token.
Discussion
Another problem will arise when we want to use this authorize method: How does resource server get the access token?
- Resource server has to
get access token by itselfbefore whenopts.token_endpoint_auth_method = "bearer_token". Oauth2 support client_credentials authorization grant. So RS can use this grant type (in token endpoint) to get it's access_token.
But now the project only support authorization_code grant type. If it's ok, I will open one more issue for supporting client_credentials grant type.
Why would you want this i.e. what is the use case?
My usecase is: Authorization server I'm using only accept introspection request that has proper bearer token or credentials (client id, client secret) of the client that introspect token was issued for.
So as resource server, I do not have the credentials of requested client (that the introspect token was issued for) so I can't make the introspection request now if I don't using bearer token authorization method.
A resource server should have its own credentials to introspect the token.
Resource server has its own credentials. In this use case is for acquiring itself access token by client_credentials grant type.
But the problem is at introspection endpoint, authorization server does not authorize RS's credentials, it only authorize client credentials that introspecting token is issued for (as I describe above). Of course RS does not own that introspect token.
That seems over-engineering: if the resource server has credentials to execute the client credentials grant so let's then use those to talk to the introspection endpoint instead of jumping through hoops. I don't feel we should support one-off behavior like this. In any case a resource server is not a client and should not need to implement the client credentials grant to do what it needs to do.
The RFC7662-section 2.1 already mentioned and showed the example for this bearer token authorization behavior. There are authorization servers support this authorizing process. So I think it is reasonable to implement this behavior in lua-resty-openidc project.
I'd be willing to accept a PR with a statically configured access token, or (as done in mod_auth_openidc) and/or one where the introspected token is also used as a credential (header) in the introspection request.
Thank you for labeling this issue. About the enhancement:
- A statically configured access token:
Does it mean configuring access token in
optsparameter? (like another config). What do you think about supporting client credentials grant type in token endpoint? (to enable resource server could get its own access token, don't need to configure statically) - The introspected token is also used as a credential (header) in the introspection request:
This second method is invalid because authorization server implementation
does not allowthis method: using the same introspected token for header authorization credentials. The reason is, as RFC7662-section 2.1 said:To prevent token scanning attacks, the endpoint MUST also require some form of authorization to access this endpoint, such as client authentication as described in OAuth 2.0 [RFC6749] or a separate OAuth 2.0 access token such as the bearer token described in OAuth 2.0 Bearer Token Usage [RFC6750].In short, need to use "a separate OAuth 2.0 access token" toprevent token scanning attacks. So will not make this second method.
well 2. is about a specific server implementation that is also a one-off
About 1. A statically configured access token: Do you mean by these? mod_auth_openidc OIDCOAuthIntrospectionClientAuthBearerToken I understand that I could put the access token to opts
But, What about supporting client credentials grant type when requesting to token endpoint? If that is ok, resource server can get its own access token to request resource from authorization server, in this case, that resource is access token's information.
and of course don need to statically configured the token.
if you have a PR @bodewig and I will assess it; I don't think it is worth the complexity though, it is a one off