lua-resty-openidc icon indicating copy to clipboard operation
lua-resty-openidc copied to clipboard

Support bearer token authorization method for introspection endpoint

Open linhdangduy opened this issue 6 years ago • 11 comments

Environment
  • lua-resty-openidc version (e.g. 1.7.0)
  • OpenID Connect provider (e.g. Keycloak, Azure AD)
Expected behaviour

In simple version:

  1. Config: opts.token_endpoint_auth_method = "bearer_token"
  2. With above config, introspection endpoint request headers will be built like this: headers.Authorization ="Bearer " .. access_token
  3. 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 itself before when opts.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.

linhdangduy avatar Mar 28 '19 11:03 linhdangduy

Why would you want this i.e. what is the use case?

zandbelt avatar Mar 28 '19 11:03 zandbelt

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.

linhdangduy avatar Mar 28 '19 11:03 linhdangduy

A resource server should have its own credentials to introspect the token.

zandbelt avatar Mar 28 '19 11:03 zandbelt

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.

linhdangduy avatar Mar 28 '19 12:03 linhdangduy

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.

zandbelt avatar Mar 28 '19 12:03 zandbelt

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.

linhdangduy avatar Mar 28 '19 12:03 linhdangduy

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.

zandbelt avatar Mar 28 '19 12:03 zandbelt

Thank you for labeling this issue. About the enhancement:

  1. A statically configured access token: Does it mean configuring access token in opts parameter? (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)
  2. 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 allow this 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" to prevent token scanning attacks. So will not make this second method.

linhdangduy avatar Mar 28 '19 13:03 linhdangduy

well 2. is about a specific server implementation that is also a one-off

zandbelt avatar Mar 28 '19 13:03 zandbelt

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.

linhdangduy avatar Mar 29 '19 10:03 linhdangduy

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

zandbelt avatar Mar 29 '19 10:03 zandbelt