Simultaneous use of an api key and an access token in the OAuth2 authorization flow - api

I'm auditing an API whose client is a mobile application using the OAuth2 workflow but I'm missing something. I have a first endpoint of the /token.oauth2 API which allows me with credentials to get an access token needed to call other endpoints of the API. So far OK but on top of that I have an "x-api-key" which is transmitted along with the access token and if both the API key and the access token are not present, the server sends me a HTTP 401 response.
I can't find any mention of a connection flow using both an "x-api-key" and an access token in the OAuth2 standard. When do you think?

Related

ID token usage when using "Log in with Google" in a mobile app

Suppose that I have a mobile app with a frontend and a backend server.
My understanding is that -- when a user logs in the app with "Login with google", the frontend sends a request to the google auth server, and gets back an ID token. The documentation says that the frontend can then send the token to the backend server to establish a session. I imagine that means the token can be used in session-based authentication?
If I were to use token-based authentication (as opposed to session-based), do I just attach the ID token in every server request, and have the backend verifies it each time when processing a request? this page suggests the ID token should not be sent to the backend API. Which leaves me wonder what the correct procedure is for token-based authentication when using log in with Google.
So my question is: Does my server need to create an access token from the ID token from Google, and send it to the frontend, so the frontend can attach that access token in the API requests for authentication?
Thanks
Login with Google is an identity provider (IDP) operation. A full OAuth solution, including an authorization server (AS) looks like this:
Mobile app uses system browser to redirect to AS
AS returns a redirect response to the system browser, which routes to the IDP
User signs in at the IDP
IDP returns an authorization code to AS
AS swaps it for IDP tokens and carries out validations
AS issues a set of tokens to the app. This includes an access token (AT) with whatever scopes and claims are needed for business authorization to work.
Mobile app sends AT in API requests
API authorizes using scopes and claims from the access token
So ideally plug in an authorization server, to get this out-of-the-box behaviour. Another option is to implement your own token service, and issue your own tokens. That is less recommended though, since it requires more detailed understanding of the underlying security.

OpenID Connect Hybrid flow for authentication only

I have a mobile app and I want to use OpenId Connect to authenticate users against an external auth provider. I only need the id_token to get the users' email address, I don't need an access token (at least for now).
Are there any vulnerabilities of using a hybrid flow where I do the first request on the front channel and I set response type = code id_token?
If/when I'm going to use an access token, I plan to send the code to a backend to do the exchange for an access token. I'm just not sure if there are any vulnerabilities to retrieving the id_token on the front channel.
The standard flow for mobile apps should be to redirect with response_type=code as in step 8 of my write up.
You then get only an authorization code and perform an authorization code grant message to get tokens. Whether you get an access token should be configurable in the Client entry in the Authorization Server.
You should use PKCE parameters so that no-one can get tokens if they happen to intercept the authorization code.
In the event that you can't prevent an access token from being returned you can just discard it from memory.

SPA + API Server + 3rd Party OAuth Authentication

Say we have SPA, OAuth service(Google or FB or Linked in) and an App server(our API) which servers the SPA to client.
Our SPA authenticates from client side with OAuth against 3rd party, say google or linked or FB, the method to use is said to be " implicit flow". Which returns the access token by passing an extra step.
Now how do we use this access token to communicate with our API. They are decoupled.
At this point client app(SPA) has the token and the FB|GOOGLE|LINKEDIN user_id which we got from the 3rd party OAuth.
Now lets say we are making a GET request to our server and it has to be an authenticated request. How do we use this token that we got from the OAuth
1) Do we make an API call from SPA to our APP server(our api server) with that token we got from OAuth and we remake the another call to the OAuth service again from the APP Server this time with the same token and make sure it is a valid token and create a JWT from that token and use jwt for the following api calls.
2) Or we implement a standard server side OAuth implementation using FB|GOOGLE|LINKEDIN and after authentication we save that access token on server side for that user and serve the SPA to client and pass that access token we got from OAuth server to client. Now that token can be used for following calls to API calls.
3) Or we implement a standard server side OAuth implementation using FB|GOOGLE|LINKEDIN and after authentication we save that access token on server side for that user and serve the SPA but this time create a JWT and serve that to client and client can now use the JWT for following calls.
I do not know what the right way is. Or if it is even a good way to Authenticate using OAuth with SPAs since Implicit Grant apparently is not a good way to go.

Generate Access Token and validate against IdentityServer4 through Azure API Management

I have an external endpoint which is going to hit the Azure API gateway and that would route it to the backend API which is protected by IdentityServer4 authorization.
I am getting the access token if I hit it through the Postman client with the interactive UI from IdentityServer.
Is there a way I can get the access token required from the Azure API Management to validate against the IdentityServer4 and append it to the header in the request to the backend API?
Yes it is possible to achieve it through custom policy. You can ask your external API-Client/Consumer to paas in credentials in heaser, and then you write a policy inside inbound to can read those user credentials and do a API request (similar to your postman) and get the access token. You can then append the same token and let your request gets forwarded to backend API.
As per your problem statement, this should work. In case not, you might have to explain your scenario with more description/steps.
Here are some of the reference materials for you, I hope it helps.
https://learn.microsoft.com/en-us/azure/api-management/api-management-advanced-policies#SendRequest
https://learn.microsoft.com/en-us/azure/api-management/api-management-sample-send-request
Postman has a luxury of a human user seeing the UI and authorizing API access and IdentityServer4 to issue a token for Postman. There is no such luxury when call is being processed by APIM server, as you could send request for token to IdentityServer4, but who would be presented UI to authorize the action?
The only way is to provision some sort of secret to APIM (header, query, certificate) that would be recognized by IdentityServer4 to allow it issuing tokens for APIM. If such secred is available you could use send-request policy to make a call to IdentityServer4 and obtain required token.
Or make sure that every request to APIM has a token already.

JWT handling with WSO2-AM

we plan to introduce an API management solution and we're currently setting up a proof of concept with WSO2 AM. We want to use the WSO2 API gateway to check whether a certain consumer application is allowed to use an API and to throttle the request rate.
I work on the identity workflow and I wonder how a consuming application can pass a JWT token to the backend service with WSO2-AM in between.
First, this is our current scenario:
Without API gateway
The consuming application gets a JWT token for its carbon user from an identity provider. The JWT contains some claims about the user, e.g. the roles he/she belongs to.
The app calls the service an passes the JWT token in the Authorization HTTP header like: Authorization: Bearer
The service validates the issuer and signature of the JWT and retrieves the claims from it.
So, this is pretty straight forward. Now we put an API gateway in between the application and the service:
With API gateway
The consuming application gets a JWT token for its carbon user from an identity provider.
The consuming application uses OAuth2 to get an access token for the following API calls. We can use the client_credentials grant type and simply pass the the client id and client secret. I haven't yet tried it, but we could possibly use the JWT grant type (see https://docs.wso2.com/display/ISCONNECTORS/Configuring+JWT+Grant+Type) and use the JWT for passing user information to the API gateway.
The API gateway validates the JWT against the public key of the identity provider when using the JWT grant type.
An access token is returned to the app.
The app sends an API request to the gateway and passes the access token in the Authorization HTTP header.
The gateway validates the access token.
The gateway forwards the API request to the service.
And there is my problem: How can the JWT from 1/2. be passed to the service?
There is a documentation for "Passing Enduser Attributes to the Backend Using JWT" (see https://docs.wso2.com/display/AM210/Passing+Enduser+Attributes+to+the+Backend+Using+JWT), but this would introduce a new JWT, issued and signed by WSO2-AM, and I'm not sure, whether this JWT contains all information from the JWT used to create the access token (or even the original JWT).
Another way I could think of is using a custom HTTP header for passing the JWT through the gateway to the service. I cannot use the Authorization header (as we do without the API gateway), because WSO2-AM expects the access token in that header.
Since I'm not happy with either solutions, I want to ask the experts: How would you solve this?
Thanks,
Torsten
The only possibility I can think of is to send the JWT token in a custom Header for the backend service.