Understanding the need of client id, client secret in oauth 2.0 - security

I have a web site that requires user to log in by providing their email and password to gain access token, where the access token token is used to access api.
User can then gain access to read/write with the scope provided by the access token.
So, what I would like to understand here is that what roles does client id and client secret play in such a case, and what benefits can implement client id and client secret provide? Because i really do not see the need of implementing client id and client secret since user may just use access token to gain access right.

You don't have to issue client IDs if you can achieve what you want to do without them. For example, if you have privileges to handle email (user ID) and password directly, you don't need a client ID.
In general, client IDs are needed only when you want to allow (third-party) client applications to access (your service's) users' data with restricted privileges. In this case, each client application must be given authorization by a user. As a result, your system will need client IDs to know which client application the user has granted permissions to.

BY using client id/ secret you can potentially control which clients are allowed to connect to your API and make decisions such as rate limit them or block them. This is the way that e.g. Twitter can ensure that no other twitter client is allowed to have over 100,000 users.

Related

Is storing an access token for a third party resource on user's browser secure?

I am learning about different Oauth2 flows but it does not provide any guidelines on securely persisting different kinds of access tokens in different scenarios and I could not find relevant information on the topic by Google-fu.
I am wondering if is it safe to save access tokens in a secure frontend context like httpOnly cookie and optionally directly calling the api from the browser without proxying it through the application server?
It appears more secure to me because access tokens unlike passwords cannot be hashed, the means to recover all access tokens (if encrypted) must exist on the server otherwise it would not be able to call the service on behalf of the user. So, were the application server compromised so would the access tokens of all users.
Am I missing some context here or is it correct?
If you think about sharing your own access token with some users user agent (browser), then this solution is never secure. The user agent (browser) is something working totally on behalf of the user. The user, if he wants to, may have access to any kind of resource the user agent operates with. Sharing a token with the user agent is like sharing the token with the user himself.
Whichever method you choose, you need to ensure your backend verifies the token (e.g jwt).
You probably wouldn't need to verify a secure cookie because a secure cookie cannot be accessed/modified by the browser.

Are AWS Cognito User Pool ID and App Client ID secret?

So 2 questions.
are the UserPoolId and AppClientId secret for Aws Cognito user pools?
if so how do you keep them secure? All the libraries I have seen (aws-amplify/amazon-cognito-identity-js) seem to be exclusively client based.
What am I missing here. It seems like you give any malicious user with JS access keys to the Cognito kingdom with these 2 pieces of information.
They are not secret.
In fact, the ID token contains the iss claim (property), which is the User Pool ID, and the aud claim, which is the App Client ID.
The Access token contains the iss claim, which again is the User Pool ID, while it's the client_id claim which represents the App Client ID.
Should either of these tokens be intercepted by a bad actor, then they can decode the tokens, as they are just base64 encoded (not encrypted).
However, just knowing these 2 pieces of information is not usually terribly useful for an attacker, as long as the JWTs are validated correctly.
It does not give the attacker access to the User Pool itself as that requires AWS credentials, which are only assigned to users, or identities that have already been properly authenticated (and then issued credentials e.g. by ID Pools).
In terms of accessing an api, an attacker might want to modify the payload in some way in order to change the data in the request. For instance they may want to change a hypothetical role claim from user to admin in order to escalate privileges and access areas that they shouldn't. This is mitigated by correctly validating the JWT tokens server-side to ensure that the payload has not been tampered with.
Another type of api attack could be to use a token that was correctly authenticated for one api to access another api (JWT substitution). This is mitigated by validating the iss and aud claims in order to confirm that the JWT was specifically issued to the expected User Pool and App Client.

Authenticating users via OAuth 2.0 from a trusted SPA?

I have a custom OAuth 2.0 authentication server deployed alongside my secured API. I also have a single page application delivered as static content by an nginx deployment. I'm now confronted with the issue of how to authenticate users of this SPA without an active backend through which to proxy a password grant -- I obviously cannot embed the client secret in the SPA.
What solutions exist for such an issue?
I have discovered that the resource owner password credentials grant may be just what I'm looking for. By using this, I would be able to send username and password credentials directly from my trusted SPA using an established client ID. If I restrict this grant to only be valid for this particular client and validate the origin of the request, I can see this being a reasonable compromise.
My question then becomes, how do I create this client and the requisite associated user? Does that not imply that there is some special user account in my system with this associated privileged client? OAuth 2.0 seems to imply that clients must be associated with a user of some kind. Do I seed these special user and client objects when my application is deployed? Is that secure?
I think the implicit flow could be used just fine.
User is redirected from the SPA to the OAuth2 server
User authenticity is verified
User is redirected back to the SPA along with tokens
For the server-side API, you need to decide whether you want to use access tokens or ID tokens (OpenID Connect - OAuth2 extension).
If user's permissions for the API are stored at the OAuth2 server, the SPA may ask a user for some of the permission that will be included in the access token. This is a permission delegation and it can be handy if there are more application each requiring different permissions.
If the OAuth2 server doesn't hold the permissions and the API manages them itself, it's probably more suitable to use ID tokens, because they represent identity of the caller and can be verified without accessing the OAuth2 server on every access.
The API probably doesn't need to have its client_id, since it just accepts tokens - it doesn't request them - it checks that access tokens contain permissions for actions users invoke or validates ID tokens.
The SPA needs to have its client_id with registered redirect_uri-s. No client secret needed, since SPA-s cannot keep them safe. It has to be deployed using HTTPS to secure the transferred tokens.

How to create JWT when a Client needs token for accessing multiple Audience?

I have created AuthorizationServer using OWIN/Katana OAuth 2.0 Authorization Server. It is configured to use JWT as the AccessTokenFormat. The SigningCredentials here are derived from Audience Secret that is unique to each Audience.
I want to build a Client that uses this AuthorizationServer to get a token for using an couple of API's I've built (resource / audience).
I see in OAuth there is no concept of Audience (JWT concept), the only thing closest to this is a Scope. I can pass multiple scopes (audience) from Client but I don't understand how can I create a JWT in this case since multiple Audience are required to be able to validate the resulting token.
Any help or guidance appreciated.
You should be careful not to confuse two different concepts. The Audience claim indicates for who the access token is intended. You can only use it for services that have that value configured in the allowed audiences.
Scopes limit what the client can do with the token on the service. For example, one scope may allow the client to post to your feed, while another scope gives it access to your list of followers.
So you would typically need two different tokens to access two different APIs. That does not mean the user needs to authenticate twice though.
The authentication happens on the authorization server and while the user is still logged in to that server, he/she won't be prompted for credentials again. The user will be prompted for consent the first time they try to access a new API.

Understanding authentication flow with refresh and access tokens on nodejs app

I know there are already many posts about Oauth, Oauth2, JWT, etc.. I have read many and I more confused than ever so I am looking for some clarification. I will propose my view on the subject and I hope somebody can tell me if my implementation is secure enough or what I am doing wrong and how to improve it.
I am building an API Rest server for serving my resources to my users. Let's suppose it is a bank app where users can deposit, withdraw and transfer money.
I am using nodejs, hapijs, jsonwebtokens, and bcrypt for my server. I want to implement two token authentication flow (Oauth2).
This is the way I am doing it:
User logs in to the auth server by giving some credentials (username and password).
The server verifies the user's credentials, if they are valid, it will grant access to the user and return a refresh token and an access token.
These tokens are saved into the local storage of the browser or mobile device.
The access token:
is signed as a jsonwebtoken.
contains issued date, expiration date (5 min), user data (id, username).
The refresh token:
is signed as a jsonwebtoken and encrypted with bcrypt.
contains a unique identifier
may contain an expiration date
is saved in the database.
As long as the access token is valid, that means, it has not expired and contains valid user data, the resource server serves the user the requested resources.
When the access token is no longer valid, the auth server requests the client to provide a refresh token in order to issue a new access token
The server receives the refresh token from the user, decrypts it, compares it to the one in the database, checks if it has been revoked, and checks its unique identifier.
If the refresh token passes all tests, the server issues a new access token to the client.
If the refresh token fails one test, the server requests the user to re-authenticate.
Notes: I am trying to avoid the usage of cookies.
Questions:
If the user is able to steal an access token, I guess it can also steal the refresh token. So, how can I make the refresh token more secure?
Is my perspective of the Oauth2 flow correct?
What can I improve?
Am I missing something?
The reason OAuth2 is so confusion to many people is because it uses different authentication flows depending on what kind of client is used.
OAuth2 distinguishes two client type, confidential or public. Next to that, there are 2 grant flows that are redirection based (auth code and implicit) which are meant to be used with a browser or browser control.
The other two flows (resource owner password and client credentials) are meant to be used from non-browser apps (CLI, background services, trusted mobile clients).
I've described the different flows and when to use them in more detail in this answer here.

Resources