I have successfully setup Kong v0.11.1 and secured APIs using oauth2 auth code flow.
oauth2 plugin was addedd on API level.
config.global_credentials = true
The issue is that if I generate a token for authenticated_userid = user1, I can use the access token to make a successful call to the upstream API and if authenticated_userid = user2 is making call with the same access token generated for user1 the request is successful as well.
Is there a setting in Kong that needs to be set so it can validate the authenticated_userid with the access token on each call to the upstream API by the client app or do I have to implement this validation using the Upstream headers?
Related
We have several microservices that communicate with each other and all these microservices use Oauth2 authorization to allow access to its API. The flow starts from the UI where we use the standard 'authorization_code' flow and finally get an access_token to invoke a specific API-1 service (Registered for client_id '123'). The UI then sends a request to the API-1 (client_id 123) and our API-1 now verifies the access token passed with auth server. Once it is valid this API now wants to communicate with another API (API-2) (Our internal microservice) which needs an access_token. We cannot re-use the same access_token as it is intended for a specific client. API-1 could use a token exchange to talk to API-2 but the developers of API-1 do not wan to do any token exchange. What are the options we have in this case?
Thanks
The typical solution is to let API1 contact your token service, using its access token and exchange it using the token exchange standard, for a new access token to access API2.
See OAuth 2.0 Token Exchange and check with your token provider for details.
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.
I am creating web and mobile apps that reimplement an existing desktop app via the desktop apps publicly available API. This API only provides the Authorization Code Grant path for authentication, which would require me to either:
somehow securely store the client secret in the app
Implement PKCE & Implicit auth endpoints in my webserver as a pass-through to the API
Have my own auth system (via auth0 or equivalent), which the user then links to their API account
Is 2 possible, or is 3 my only real option?
Yes, 2 is possible, and is much more simple than I imagined. In the following examples Client is the web or mobile app, Server is your server, and API is the api you are trying to reach that only supports Auth Codes
for web (Implicit):
Client sends a standard Implicit request to Server
Server parses this request, then restructures it as an Auth Code request and forwards to API
API validates user login, and sends Auth Code to Server
Server sends Auth Code back to API
API returns access token and refresh
Server returns only access token to Client
for mobile (PKCE):
Client sends a standard PKCE request to Server
Server parses this request, then restructures it as an Auth Code request and forwards to API
API validates user login, and sends Auth Code to Server
Sever sends Auth Code to Client
Client sends Auth Code and Verifier to Client
Server verifies sends Auth Code back to API
API returns access token and refresh
Here is my plan (authorization code flow) of implementing such login/register logic. (The third-party only provided the OAuth2 API)
First the SPA frontend will send a GET request to the third-party
GET https://www.example.com/oauth2
client_id=dummyclient
redirect_uri=https://mysite/callback
response_type=code
scope=openid
Then if the user agree to give his/her openid to mysite then the fronend will get a 301 HTTP response.
---> 301 https://mysite/callback?code=dummycode
Then the browser will redirect the page to mysite/callback and it will reload SPA and expose the code in URL which can be captured by the SPA then it will send the code to the real backend callback.
GET https://mysite/api/real-callback?code=dummycode
When the backend get the code, it will send the code to the third-party to exchange an access_token. When the backend get the access_token, it will fire an API request to get the user's openid then decide whether to let the user login or register as a new user. At last it will give back a HTTP response to our SPA frontend which contains the access_token in my OAuth2 system or a 401 unauthorized response.
So my question is how to prove that the real callback is invoked by my own clients (Because if some attacker get my frontend embedded client_id then he can fake the OAuth2 request and phishing the user to agree. After that the attacker will get a valid code then he send back the code to my real callback. Finally, he will get the user's access_token in my system.) How can I use OAuth2 to do authentication without the end user's providing additional information like password.
I would suggest you to change the OAuth2 flow to Implicit and ask for both access_token and id_token (OpenID Connect). Your SPA will get the tokens, send the ID token to your backend, which can use it to decide whether it's possible to create such user. The SPA can use the access token to call protected resources.
This way,
only the SPA will be an OAuth2 client - tokens will not be used by two applications (SPA and backend),
you will have just one redirect URI,
you will not need to transfer tokens from the backend to the SPA.
Update: Without OpenID Connect
If you cannot use the id_token, you could send the access_token to your backend and the backend can get the user's username by sending to token to the Introspection endpoint https://www.rfc-editor.org/rfc/rfc7662 (from the response username attribute). The username attribute is optional. Your OAuth2 server may return even more info (such as name and email).
This Introspection endpoint requires authentication, so to use it, your backend will have to be a registered OAuth2 client with its own client_id and a secret.
I've been requested by a client to incorporate OAuth authentication within a REST service. The setup I am working with is client/user accessing a service directly. The service is not connecting to another service. I was asked to have OAuth implemented so that users/clients are authenticated by supplying the username and password in the authorization request and not have them log in via a web page. My client has read information from other sites like paypal (https://developer.paypal.com/docs/integration/direct/paypal-oauth2/) which lead him to believe this was possible. So my underlying question is how do I configure an Authoirzation Server to allow for authorization when supplied a password and username directly?
Peter
The flow is called "Resource Owner Password Credentials Grant" and described in 4.3. Resource Owner Password Credentials Grant of RFC 6749 (OAuth 2.0).
In this flow, a client accesses the token endpoint without accessing the authorization endpoint. So, check the configuration of the token endpoint of your authorization server.