How to prevent REST API parameter alterations - oauth

I am building a REST API to expose all todo lists saved by a particular user. User authentication happens using OAuth2 protocol. I have an API GW that authorize access to this API
based on the access tokens. The API has an input parameter for user. All todo lists saved by the user specified through this parameter is returned by the API
Lets say user1 gets an access token after successful authentication. He uses that token to call this API, but sets the 'user' parameter to user2. Since the API GW gives access to
the API (as there is a valid access token), the request passes to the service which returns all todo lists of user2.
How does one prevent this from happening?

Usually, you would want to store the access_token and the user_id together as a 1:1 relationship in somewhere like a SQL database. After that, you would be able to check the ownership of an access_token in your API.
Besides, if you're using JWT format for access_tokens, you may store the user_id in the token's claims instead of storing in a database.

Related

Identify user when receiving access token in web API using ADFS 2019 (oid claim)

I am trying to request an access token from ADFS 2019 containing an unique user-identifier which represents the same user across multiple applications.
I want to fetch an access token as a native client in order to request data from my web API. In order to return user-specific data, the access token needs to contain an user-identifier for the user who fetched the token from ADFS and sent it in the header of his request to the web API. The web API can then identify the requesting user.
Currently, the only user-identifier which the access token contains is the sub claim. Unfortunately, according to this, the sub claim is not the same identifier for a user across multiple applications. Since I need user-identifiers in order to link user-dependent data with users in a database which is used by several applications, I need an unique user-identifier which always represents the same user, no matter the application. According to the link above, what I am looking for should be the oid claim, but it is currently not contained by the access token I receive.
How can I add the oid claim to my access token?

How should I use the id token returned to me by Google after a successful code exchange?

I am not clear on what exactly I should do with the id token from Google after the initial verification.
I'm developing on expo/react native and get the id token locally. Then, I send it to my server and verify it using google client libraries. Once it's verified what should I do with it?
Ideally I could use it to protect my api routes (express) but id tokens expire after 1 hour and I'm not sure how to refresh them with the client library. So, I don't know how I would do this.
Is that the intended use for id tokens? Should I instead be signing my own jwt and sending that back to the client? Then, the client could send that in the auth header of each request to a protected routes.
Google says:
After you have verified the token, check if the user is already in your user database. If so, establish an authenticated session for the user. If the user isn't yet in your user database, create a new user record from the information in the ID token payload, and establish a session for the user. You can prompt the user for any additional profile information you require when you detect a newly created user in your app.
https://developers.google.com/identity/sign-in/ios/backend-auth
Do I use the id token to "establish a session for the user"?
Yes, the ID-token is only used to create the local session, perhaps also create a local entry in your local database if that is used.
The ID token also have a very short lifetime, like 5 minutes in some systems. So it has no long-term use.
The ID token is intended to authenticate the user. It gives you information about the authenticated user, it should not be used to allow access to your endpoints. Access tokens or sessions are intended to do so. So in your case, you should do exactly as your gut feeling tells you - create a session for the user basing on the data you got in the ID token.
If you have your own Authorization Server you can use the ID token to issue an access token and return the token to the frontend app, then use the access token to access your backends. Have a look at OAuth flows if you would want to go this way.

What does `client` header value represents in devise_token_auth

I am trying to implement token based authorization in rails, with devise_token_auth (https://github.com/lynndylanhurley/devise_token_auth#conceptual).
When I post uid and password against sign_in method, it returns access-token, client (and uid itself) in header. I understand that token based authorization works like this:
User posts uid(id) and password to api server.
Api server validates the uid and password
Issues Token and returns it, if the uid and password matched.
Client receives the Token.
Client whenever client wants to access the authentication required apis, Client uses the uid and the Token in order to prove that this client is in fact already authenticated.
I can understand that access-token corresponds to the Token described in above explanation. That leads to me a question of what the client header value is, because it seems that, according to the official Wiki (https://github.com/lynndylanhurley/devise_token_auth#usage-tldr), devise_auth_token library not only use requires access-token but also client value.
Question:
In devise_token_auth, what is the purpose of client header value? Why is it also needed for identifying the user? Couldn't that be included in (or, concatenated to) the access-token value?
The client header is generated for every different device accessing the API. Its purpose is to maintain more than one session active for a specific user (web client, mobile client, etc.).
You can test this by signing in with the same user on 2 separate web clients and checking user.tokens, there should be 1 set of tokens for every client.

How are access tokens distinguished between resource providers in OpenID Connect?

I am working on creating an OpenID Connect (OIDC) Provider based around django-oidc-provider. I have been reading up on the OpenID Connect Spec, and I cannot figure out how access tokens are unique for a certain application.
Consider the following example with a user, Bob:
Bob wants to login to application A, so he goes to its interface and is redirected to the OIDC Provider. After authentication he is redirected (implicit flow) back to Application A with an ID token and an access token. He then makes a request at "/image/1" to A's API with his access token. The API uses the access token to reach out to the OIDC Provider to assert the user's identity as Bob. The API then returns the data at "/image/1" for user Bob, assuming that info exists. Bob continues to send his access token to A's API for any subsequent requests.
Then, Bob decides he wants to access application B's API. He sends B's API the same access token that he used with A's API. B's API reaches out to the OIDC Provider with the token and asserts the user's identity as Bob. B's API then returns the requested info for Bob.
What prevents this from happening? I see at least two possible solutions to this:
When reaching out to Google's token validation endpoint the "aud" parameter is returned. Application B's API would have to check this parameter to decide that the token is not valid for it's own API?
An additional scope must be added when requesting the token that is specific to the resource provider say "app-A-api". Then when an API is validating a token, the API would ensure the token contains the needed scope.
Which of these methods, or others, are in line with the OIDC spec?
If one of the above should be used, am I correct in assuming I should add a new /tokeninfo endpoint that returns the scope or aud, rather than add that info to the info returned at the /userinfo endpoint?
Any input is appreciated. I think a lot of my confusion comes from not seeing the "scope" param being used to delegate access to a resource provider in any OIDC examples.
I think the thing you are missing is that the application A and its API are two separate applications. So the tokens are issued for the application A. If the app-A-api uses the access token just for the user authentication, it's better to use an ID token - it can be validated without accessing the OAuth2 server. In this scenario, the app-A-api manages its user permissions by itself.
If the app-A-api needs the token to get a list of scopes (permissions) of its client, then use the access token. But in this scenario, the app-A-api (and app-B-api) are just accepting the access token - they are not the target audience (aud attribute) of the token. The application A is the audience of the tokens.
The APIs just check whether the access token contains scopes relevant for them. They trust the token issuer and it's up to the users to decide whether they trust the application A to perform actions on their behalf.
As an example, if a JavaScript application C (app-C) uses just Google Drive and Google Plus for its actions, then app-C will ask its user for an access token with scopes belonging to Google Drive and Google Plus. It will be just one token and both Google APIs will accept it.
And about the tokeninfo endpoint, it has it's own RFC called OAuth 2.0 Token Introspection, so you can check it.

get separate access token for a particular user in wso2 IS

I have created Service Provider and wso2 IS successfully integrated with LDAP, tested API and able to generate access token for user.
The wso2 IS generates same access token every time for a single user, even if i hit /oauth2/token api multiple times, Is it possible in wso2 IS to
generate separate access token for same user everytime i call /oauth2/token
wso2 IS able to handle this type of token management
Thanks
WSO2 IS generates a unique access token for the combination of
1. OAuth2.0 client ID (client/application)
2. Authorized user (resource owner)
3. Approved scopes (for the unique set)
If a valid access token already exists for the above combination in ACTIVE state that token will be returned. If you need a new token one of the above parameters MUST change.
A new feature JIRA has already been captured with regard to this:
https://wso2.org/jira/browse/IDENTITY-4404

Resources