Kong OAuth2 Plugin Client Credentials Flow provision_key not validated - oauth-2.0

I have configured the Oauth2 Plugin in Kong with Client Credentials Flow. All endpoints are accessible and it works as expected, except the fact that I can request an access token from the {service}/oauth2/token endpoint without providing the provision_key in my post request. (It returns a valid token even when I only post grant_type, scope, client_id and client_secret as parameters)
Is there something I need to enable on the plugin configuration? Or is it somehow so defined that with client credentials flow(namely, the token endpoint), the provision_key is not needed?

The provision_key is only needed if you want to also specify authenticated_userid with the request. This is a Kong specific extension of OAuth2 which is not really compliant with the standard, which is why I guess they chose to not really document it.
If you are using the Client Credentials for what it's intended for - server to server backend communication without an explicit user context - Kong will accept a token request without the provision_key, just as the OAuth 2.0 RFC specifies.

Related

Kong Gateway - Token exchange for OpenId Connect plugin using Authorisation Code Flow

I’m trying to secure a Kong Gateway service using the OpenId plugin. The redirect to the ID provider works fine, and then the provider redirects back to my service route with a code and authState in the query string. I was expecting that Kong would intercept this and exchange the code for a token, and then pass that down in the header to the ultimate http service.
Am I misunderstanding how this works? Does my http service need to manually exchange the code for a token - that seems a bit strange?
I’ve tried with ngrok as well - they provide a redirect oauth endpoint which exchanges the code for the token and passes it on to the protected http service, so I assumed Kong worked similiarly (although I can’t find a redirected URL, so I was thinking perhaps Kong inspected the query string and if there is a code it automatically exchanges it for a token before proceeding with proxying the route)

In OAuth2, is the /introspect endpoint meant for the OAuth Client to call, or the OAuth Resource Server to call?

I'm learning about the OAuth /introspect endpoint as a means to validate an Access Token. I'm using Okta, which I think is relevant to the question.
I've read online that the /introspect endpoint is intended to be called by an OAuth Resource Server (for example, an OAuth Client would call a Resource Server, providing an Access Token, and the Resource Server would call the /introspect endpoint to make sure the token is valid).
However, the /introspect endpoint (at least with Okta) requires you to provide the OAuth Client credentials (either as a basic auth header, or in the case where there is no client secret, just a client_id request param).
So, how can the Resource Server call the /introspect endpoint when it doesn't have the OAuth Client ID and/or secret? This is making me wonder if the /introspect endpoint is meant to be called by the OAuth Client instead, which to me, doesn't seem as useful.
Please refer to this article. Resource server needs to be a registered client application at Okta and client credentials in /introspect refer to this client's.
Based on my understanding the introspection endpoint is meant to be called by an API resource.
This endpoint is used by the API resource in order to validate the bearer token provided with an incoming HTTP request issued by a client application.
Most of the times this happens when the provided bearer token is a reference token, so the API resource server needs to known whether the provided reference token is associated with a valid access token. This information must be asked to the secure token server via a call to the introspection endpoint.
You can find more information here in the identity server docs. Identity server is a .NET implementation of the openid connect protocol, which is based itsel on oauth2.
This is a documentation that shows you how to call the introspection endpoint programmatically. This documentation is specific for a .NET library called identity model, but this is not relavant for your question, because the library simply implements the protocol.
As you can see in the example of the linked documentation, the client id that you need to specify when you call the introspection endpoint is simply the name of the API resource. The client secret is the API resource secret that you have defined for your API resource.
So, the source of your confusion is simply a terminology overload. In the context of the call to the introspection endpoint both of the following equations hold true:
client id == API resource name
client secret == API resource secret
This docs confirm both of my assumptions.
If it helps here are a few resources of mine, to add to Enrico's answer:
API Setup - see step 6 - you have to register an OAuth Client for the API
API OAuth Messages - see steps 16, 17 and 19 for the three types of response your API needs to deal with
API Code - for an example implementation in NodeJS

Spring Security OAuth2: Client as javascript application

I am using client_credentials grant type in my spring boot application. In client_credentials grant_type the client makes a request to the token endpoint. If the access token request is valid and authorized, the authorization server issues an access token.
localhost:8181/OUTPOST/oauth/token?grant_type=client_credentials&client_id=myClientId&client_secret=secret
The problem is my client is a javascript application. Client application wont be able to securely store the client credentials, so there is no point is having client_secret.
Implicit, password and Authorization code needs user details for generating token. But i dont have any user, i just need to validate my client application.
Which grant_type should i use to support my requirement?
The implicit OAuth2 flow is wat you are looking for. Details from the OAuth2 spec: https://www.rfc-editor.org/rfc/rfc6749#section-1.3.2
I don't think what you are asking is really valid. It is not possible to authenticate a JavaScript client securely via OAuth2 without user credentials. This would mean that everyone that can access the JavaScript app would be authenticated.
If you want to restrict access to this app without user credentials, it might be better to add network level policies instead, like IP range whitelisting.

OAuth2 authorization code PKCE without client_secret (wso2 5.3.0 IAM)

I'm currently trying to implement the OAuth 2.0 authorization code grant on a public client/native client (Android App).
Since it is impossible to store the client_secret on the device, I wanted to use this grant type with rfc7636 / Proof Key for Code Exchange by OAuth Public Clients (PKCE).
I'm using wso2 5.3.0 IAM in the backend.
The Authorization step works perfectly fine, but I'm not able to get the Access Token without a client_secret: invalid_request, Missing parameters: client_secret
Did I misunderstand the authorization code grant with PKCE wrong or did I miss some configuration in the IAM?
In comparison: It is possible with auth0.
Best Regards,
Robert
Even if you use the authorization code flow, client_secret is required at the token endpoint if the client type of your application is confidential. "4.1.3. Access Token Request" in RFC 6749 says as follows:
If the client type is confidential or the client was issued client credentials (or assigned other authentication requirements), the client MUST authenticate with the authorization server as described in Section 3.2.1.
So, change the client type of your application to public. I don't know WSO2, but I guess that it provides settings menu to switch the client type like below.
(screenshot of Authlete's web console)
The definitions of confidential clients and public clients are described in "2.1. Client Types" in RFC 6749.
Yes, the client_secret is mandatory in WSO2 IS implementation due to the Apache OLTU library that has been used internally to implement the OAuth2 feature.
Currently there is no way to register an application as a public client as explained.
However that doesn't mean there are necessarily any security pitfalls. Basically what the recommendation says is, not to embed the client_secret in a mobile app, because it makes it vulnerable. It doesn't provide any additional security for protected backend resources, because the client request is anyway not authenticated using client_secret. If you just treat the "Base64(client_id:client_secret)" as one single string it doesn't make any difference in the protocol or security of the protocol.
So when using WSO2 IS with mobile applications, following recommendations need to be followed.
Use authorization code grant type, which requires the client_secret.
Use PKCE (after WSO2 IS 5.2.0)
If you have other type of clients or channels for the same applications, e.g. like web, then register them as a separate service provider in IS and generate a separate pair of client_id, client_secret for them.
Disable "client_credentials" grant type for the particular OAuth2 mobile client you register in WSO2 IS, so that those apps can't get an access token without user authentication.
Going one step further, if you need to have unique client credentials for each instance of the mobile applications then use OAuth2 Dynamic Client Registration (DCR) to generate client credentials on the fly.
By following above 5 recommendations, it gives you the same level of security as recommended in the specification.
For Authorization grant flow you can send the request with empty client_secret. Try putting empty string like this client_secret='' and it should work as expected. You cannot request TOKEN_URI without client_secret parameter.
PKCE is used to protect theft of authorization code, Authorization code is valid for 10 minutes, when auth code is redeemed for access_token we also send code_verifier to make sure the auth code is not stoled by someone. code_verifier and code_challenge are generated together and code_challenge is used while requesting for auth code & code_verifier is used while requesting for access_token

OAuth2 Bearer token used like API_KEY

We want to make simple authorization for server-server HTTPS communication (we control both servers) like classic API_KEY: client has hardcoded (in a config) a key which use in every request. Server check if the key is valid.
Our colleague has implemented it like OAuth2 Bearer token (RFC6750)
Authorization: Bearer client_key
So the client has the client_key in the config, it's never refreshed. It works well, we have just a philosophical dispute in the company, if such "hardcoded" Bearer token is along with OAuth2 or not. (Disclaimer: I am not with any side of the dispute.)
The OAuth 2.0 protocol basically defines an access_token - which is a token that is bound in time and permissions - and two protocol "legs":
how to obtain and access token
how to use/present an access token
You do not use access tokens (since your tokens are not bound in any way) and you've only "syntactically" implemented part 2. In fact you don't actually implement OAuth 2.0 in that case. You may present the client_key just as well in an HTTP Basic header or in a query parameter, it has nothing to do with OAuth 2.0 except that you're borrowing (arguably: abusing...) its header name and format.

Resources