oAuth 2.0 - Acting on behalf of the user - authentication

I'm new to oAUth2 and I'm trying to get a few things straight.
I understand the basic principles involved with oAuth2 but I am not sure how to implement it in my situation.
I am writing an app that acts on behalf of the user to automate a manual process and perform some tasks(update/request status...etc). The API we are connecting to uses oAuth2 to grant our application permission. We plan on having the user grant our application permission when they create a new account with us.
I understand that the user will request an authentication code that is provided to our application. Then our application will use the authentication code to generate an access token.
We would like to do this only once. Then act as the user to send and receive notifications without having to have the user to log into the service with their credentials.
I am not sure how to implement this without having to store the user credentials to get an auth code since the auth code and auth tokens expire. I'm guessing that this is a common scenario.
What would I need to do to get what I want accomplished?

You can get a new AccessToken using a RefreshToken, if this is provided by the Authorization Server.
If it's not provided I would contact the Api provider, you should never store a users credentials. In fact if the OAuth protocol is well implemented as a client you should never be able to even get the client credentials. When the user has to login you should redirect the user to the Authorization Server, there the user should login and then the authorization token should be redirected to your application by the Authorization Server.
See also this explanation on Refresh Tokens from the OAuth 2.0 spec:
Refresh tokens are credentials used to obtain access tokens. Refresh
tokens are issued to the client by the authorization server and are
used to obtain a new access token when the current access token
becomes invalid or expires, or to obtain additional access tokens
with identical or narrower scope (access tokens may have a shorter
lifetime and fewer permissions than authorized by the resource
owner). Issuing a refresh token is optional at the discretion of the
authorization server. If the authorization server issues a refresh
token, it is included when issuing an access token
Note
If you request a new AccessToken using your RefreshToken and the response includes a new RefreshToken you should overwrite your currently saved RefreshToken. With other words, you should always use the latest RefresthToken you received.

Related

JWT Auth, Way to access AccessToken when you logged in

i'm having a diffculty with Access Token.
And i'm new in web dev, taking a role in front-end.
So far, my web site is connected with server for log in API, and i can verify user infomation after logged in at console.
However, i'm wondering the way to get access to Access Token which is issued from the server.
So, the logic is as follows,
When i sucess logged in with correct user information, AccessToken and Refresh Tokens are issued.
I needed a code to access to Access Token, so if i have, i can access to prevented pages (such as, MyPage)
The Access Token has 30min of expires, so after logged in 30min,the issued Access Token must be expired and lost its access rigth to private pages.
Summary !
I'm wondering the way to code the AccessToken in Client side to server side after logged in. Found some of informations that saying include Access Token in headers request in Client side.
How can i code whether the Access Token is expired after 30 min and reqesting again to issue the access-token when i access to private pages with access-token expired state.
Then, if server can find there is a refresh-token in Client side, then issues access token very easily.
Wondering should i put all of the pages that check wether AccessToken is alive?
Normally, it handle by token middle-ware between front-end to IdP(ID provider) server.
It automatically refresh the access token by refresh-token.
The middle-ware's roles
refresh token together with the access token when the user login is processed.
access token and refresh token are re-issued when the refresh is executed
saved the access token and refresh token into local storage (usually called cookies)
If an access token is expired when you execute an API, it will be able to execute the API with a new access token if a refresh token is valid
If an refresh token is expired when you execute an API, it will be able to execute the API with a new access token if a refresh token is expired after got new refresh token.
Popular IdP is Keycloak provides middle-ware for multiple languages.
Java, Javascript, Python, Spring Boot, Angular, React
sorry, I missed your question
I'm wondering the way to code the AccessToken in Client side to server side after logged in. Found some of informations that saying include Access Token in headers request in Client side.
The front-end access an access token and decode it for getting user's information, role and expires time
How can i code whether the Access Token is expired after 30 min and reqesting again to issue the access-token when i access to private pages with access-token expired state.
middle-ware takes care the life time of access token
Then, if server can find there is a refresh-token in Client side, then issues access token very easily.
Yes,
Wondering should i put all of the pages that check wether AccessToken is alive?
It stored in local storage in single place and use it from mutiple pages
There are a few things I might not agree with in #BenchVue answer:
Client should retrieve user data from ID-tokens only. Access-tokens audience are resource-server(s), can be opaque and should be used only as authorisation headers.
Authorization-server (middle-ware in the answer) defines tokens expiries. It does not refresh it auto-magically. Clients must handle tokens refreshing, which can be done pro-actively as OAuth2 token responses contain expiry in adition to the token itself (even for opaque token).
Do not code a gripped weel. Pick a lib. You're very very likely to make security breaches otherwize. Plus you'll waste a lot of time implementing stuff like:
redirection to authorization-server for login / logout when user tries to access a protected route
silent access-token refreshing (just before it expires) using refresh-token
JWT adding as Bearer Authorization header to secured resource-server
etc.

Why shouldn't I use IdToken as bearer token in an IDP context?

I am using an IDP platform (here AWS Cognito but that could be Auth0, OKTA or Keycloak) and I was wondering why I was discouraged to use the ID Token as an authorization token.
To be more specific, I will not make use of a resource server with authorization delegation from a user to a third-party app. My IDP will just let me SSO all my users on my different applications. There is no scope to grant here, only authentication claims that each service will use to grant or refuse access to resources (like an email, user ID, or the roles).
I understand I could provide my application with the id token and then create some session for my user. By why shouldn't I use the id token itself as a stateless session token, given that its signature can be checked on each application's back-end ?
And if I should use an access token over the id token - can I replace scopes by roles ? Or how should I understand the scopes in a non-delegation context ("user is usign the app himself, not giving permission" vs "user is giving all scopes to the SPA front-end which is an application in itself")
By the way, I am recovering the tokens through code PKCE flow on the front end.
The ID token only contains details about the user and how the user authenicated. so its perfect for creating a longer lasting cookie session with the user. The default lifetime for and ID-token is very short as well, like minutes. You typically throw the id-token away after establishing the sesson. You should never ever pass the ID-token around to other services.
The access token is mean to give you access to the APIs that the token is intended for.
when the user signs in, you ask for acceess to certain scopes and the scopes selected (consented) by the user , then is included in the access token (as scopes and audience claims).
In theory you can pass the ID-token to an API, bits not how its supposed to work.
See this and this for more details:

Can I use OAuth for authentication for trusted client (mobile app)?

I know how OAuth2 and OpenID Connect works. But there is still some confusion bothering me.
We develop our own Auth Server, service API and mobile app. So, the client app is trusted and we use "password" grant type. The app user repository follows the same user database in auth server.
Our customers login to the app by username/password. The app then submits the user credential to the Auth Server token endpoint, which will return the (bearer) access token and ID token (JWT) to the client.
The ID token contains basic user information so that the app can greet user like "Welcome Tony Stark!".
The access token can be used to access API (e.g. update user profile).
OAuth by design is not a tool for authentication. Ref: https://www.scottbrady91.com/OAuth/OAuth-is-Not-Authentication
My questions are
1) Do we need to verify the signature of the ID token if the client only is only interested to get the user information? Also note that the ID token is coming from the token endpoint via https connection.
2) Let's forget about the ID token. Can we treat the user has passed the authentication check (i.e. login success) if the client obtains an access token from the Auth Server? This flow is very similar to simple password login without OAuth.
3) The client can access protected APIs with the access token. Without access token, the client can only invoke some public APIs. Is it equivalent to what can be done with and without login? It seems the access token can be treated as "login session cookie".
4) There is no 3rd party involvement in my case. Everything (client, auth server, service API) is developed and owned by the same organization. Does it still make sense to use OAuth?
Typically a mobile app is considered a public client. Unless you're limiting who has access to the mobile app, it can't be considered trusted as someone could mess with the app outside of your control even if you developed it.
Also, the resource credentials grant type is generally not a good idea.
One thing is that the OpenID Connect spec requires authorization code, id token, or a hybrid flow:
Authentication can follow one of three paths: the Authorization Code
Flow (response_type=code), the Implicit Flow (response_type=id_token
token or response_type=id_token), or the Hybrid Flow (using other
Response Type values defined in OAuth 2.0 Multiple Response Type
Encoding Practices [OAuth.Responses]).
Some other reasons:
Why the Resource Owner Password Credentials Grant Type is not Authentication nor Suitable for Modern Applications
The OpenID Connect RFC says you MUST verify the ID token:
When using the Implicit Flow, the contents of the ID Token MUST be validated in the same manner as for the Authorization Code Flow, as defined in Section 3.1.3.7, with the exception of the differences specified in this section.
Although, you may qualify for this exception from 3.1.3.7 if using TLS:
If the ID Token is received via direct communication between the Client and the Token Endpoint (which it is in this flow), the TLS server validation MAY be used to validate the issuer in place of checking the token signature. The Client MUST validate the signature of all other ID Tokens according to JWS [JWS] using the algorithm specified in the JWT alg Header Parameter. The Client MUST use the keys provided by the Issuer.
If you're able to trust the client, and the user/pass check you've implemented, then you should be able to trust that an access token has been granted to an authenticated identity according to the OAuth 2.0 spec.
The access token in OAuth 2.0 also contains scopes and should limit what can be done with that access token. A login without OAuth doesn't necessarily.
It's a good idea to use OAuth to protect the credentials of the resource owner. If you were to use the resource owner credentials grant type, this still provides some benefits as the user could enter the password only when the client doesn't have a valid access token, ie, the user can enter her password once for an access token and validate the user using that instead of entering the password again or storing it somewhere.
Even though this grant type requires direct client access to the
resource owner credentials, the resource owner credentials are used
for a single request and are exchanged for an access token. This
grant type can eliminate the need for the client to store the
resource owner credentials for future use, by exchanging the
credentials with a long-lived access token or refresh token.
OAuth 2.0 RFC6749
1) Do we need to verify the signature of the ID token if the client
only is only interested to get the user information? Also note that
the ID token is coming from the token endpoint via https connection.
YES.
2) Let's forget about the ID token. Can we treat the user has passed
the authentication check (i.e. login success) if the client obtains an
access token from the Auth Server? This flow is very similar to simple
password login without OAuth.
If I understand the premise. Yes..There is no requirement for using the ID Token.
3) The client can access protected APIs with the access token. Without
access token, the client can only invoke some public APIs. Is it
equivalent to what can be done with and without login? It seems the
access token can be treated as "login session cookie".
The access token is a access (like a key) that for the OAuth Client to use that was delegated permissions from the resource owner.
4) There is no 3rd party involvement in my case. Everything (client,
auth server, service API) is developed and owned by the same
organization. Does it still make sense to use OAuth?
Yes. OAuth and OpenID Connect are used by many, many organizations and is a test solution.
You should not try to re-invent the "wheel". Use known trusted libraries for Authentication, Authorization and cryptographic operations. OpenID Connect has some certified Implementations

What to do after getting oauth2 token?

I'm trying to implement a "Sign in with ..." authentication system.
I've read several posts and articles on oauth2. Everyone that I've read stops the discussion or tutorial at getting the access token and possibly logging in the user for that session.
I understand that and can implement that part. Here's what I don't get:
When the user leaves the site and doesn't come back for a week, but they're still logged into the client, how do I log them back into my app? I know you save the access token to the DB, but how do you use that to log them back in?
If they're logged out of the client, how do you redirect them to the sign in page of the client. It seems that every time I try to log back in I'm asked to allow or deny the app again. I know that isn't standard, so how do I fix that? What do I send the client so that it knows that the user has already authorized the app?
I don't need a code sample unless someone knows of an article, what I would really like is just a high level overview of what to do with the access token after I have received and saved it.
Thanks!
EDIT:
I understand that OAuth2 isn't an authorization system in itself, but everyone and their dog has a "Login with..." option. And in order to do this it's necessary to use OAuth2 (or some form of API identifier). That's what I'm trying to do.
Does the following sound like the correct flow:
Get temporary code from auth server
Trade that for access token
Get user data from auth server and do whatever you want with it (probably save to a DB).
Log the user in, saving the refresh token as well.
Set an identifier in a cookie for the user (the access token)
When user comes back, identify them via the cookie token.
Try to make a call to the api and see if the access token is still valid.
If access token is still valid, great!
If access token isn't valid, then get a new one via the refresh token.
Is that the basic gist of using OAuth2 to help authenticate a user?
First of all, OAuth2 is not an authentication protocol. The issued access token does not sign you in, but allows you to call a web service (API).
OpenID Connect is an authentication protocol built on top of OAuth2. It allows you to get back an id_token from the authorization server that identifies the user. If you safe the token (or the info in it) in for example a cookie, you can establish a authenticated session for the user.
You also do not store access tokens in a database. Access tokens are short-lived and storing them on the server side serves no purpose.
You do store the refresh token in a database. When the client (app requesting the token) is confidential (can keep a secret), a refresh token may be issued. The client can use this refresh token to request a new access token for the API when the old token expires. This is what will surely happen when the user did not visit the app for a week.
This is what I do when using OAuth 2 tokens:
1.) You should store the access token in the local storage of your client. So once you stored it you can use it for every request you make like adding it to the Authorization Header "Bearer " + accessToken;
Don't forget to clear the local storage of your client when they logout.
2.) Basically if you send a request to the API and it returns "HTTP Error 401 Unauthorized" (Status 401) then you know that you should immediately re-direct the user to the login page because he/she is not authorized.
Well, if you are using role-based authorization then there's a possibility that the user is logged-in but is not authorized. This scenario should be handled by you. Only display actions on the UI corresponding to the authorization level of the user.
Hope this helps.

Custom (Non-OAuth) Refresh Token Implementation

I'm working on an application that uses a token-based authentication system, where the user provides their username / password and receives a token in return (the token gets saved to the database as well). Then subsequent requests will include this token as a custom header and we can use this to identify the user. This all works fine.
Right now if the user doesn't login for 3 days, we expire the token. I was reading a little about refresh tokens in OAuth and I was wondering if I could somehow implement something similar. i.e. when providing the auth token, I also provide a refresh token which can be used later to request a new auth token. In terms of security though, it seems quite similar to just never expiring the user's auth token in the first place. Should I be sending additional information with the refresh token to validate the user?
In OAuth2, the resource server and authorization server are often not the same.
The refresh token is sent back to the client when the access token is issued and when the token is refreshed. The client needs to authenticate itself (using client id and client secret) to use the refresh token. The resource server never sees the refresh token.
Also, access tokens are not stored at the server side as they have a limited lifetime. Refresh tokens are stored and can therefore be revoked.