Understanding the authorization part of JWT and session - session

So i read about how authentication is done using JWT, where we basically verify if the token is valid using a private key (assuming RSA is the algortihm). And if the token is valid, then the user is considered authenticated. And I also read about session authentication where we check if the user supplied session id (through cookie), exist in the session store (assuming mysql / redis is used to store session). If it exist, then the user is considered authenticated.
But how do we use JWT and session for authorization ? Lets consider an action such as GET invoice , whereby a user can only view the invoice that he owns.
If we consider the user is already authenticated,
how do we check if the user is authorized if we are using JWT?
And how do we do it for session ?

You are probably confusing the things. One of the benefits using JWT is to avoid maintaining sessions which is big bottle neck in scaling.
JWT (Json Web Token) carry all the information that would require it to get authenticated, you don't need to maintain the session. Every single HTTP request to server will carry JWT that would contain necessary user claims including the signature. On server you will validate the signature to verify if the token is valid or not. You can verify the token without maintaining any session and there are number of ways to do it.
Since JWT is essentially a Json object (Header, Body , Signature) , you can put in claims (emails, roles, profile etc) in JWT body. Once you verify the token , you can extract the claims including any roles and check if user is authorized to access the resource.
You must look into Open ID Connect and Tokens here

Related

Does Passport utilize guards not to authenticate users but to validate access tokens on routes where these tokens are required?

I'm a little bit confused by the documentation. It's said:
Passport includes an authentication guard that will validate access
tokens on incoming requests. Once you have configured the api guard to
use the passport driver, you only need to specify the auth:api
middleware on any routes that require a valid access token.
So it means that Passport utilizes guards not to authenticate users but to validate access tokens on routes where these tokens are required. Did I get that right?
In this case, validating the access token is authenticating the user. To understand why this is the case, let's walk through a simplified authentication flow using JWTs (let's ignore oAuth2 for a bit).
The user is logging in on the website. This triggers a POST /login request, with the username and the password in the request body.
The backend validates the users credentials. If the credentials are valid, it will issue a JWT, which will act as an access token. The JWT payload will contain some data that allows the backend to identify a user, e. g. the user id. The JWT then is signed with a secret that only the backend knows.
The backend will return the access token to the client, who has to include the access token in any subsequent requests to the server. Usually, the client will provide the token in the Authorization header.
When handling the next request from the client, the backend will extract the access token from the Authorization header and check its signature. If the signature is valid, the backend can be sure that the token data has not been manipulated, e. g. by changing the user id on the access token. With a valid signature, the backend can extract the user id from the tokens payload and set the User model for that specific id as authenticated. With an invalid signature, the backend will probably return something like 401 Unauthorized.

OneLogin programmatic session cookie validation - No browser

I have the following scenario that I am curious if it is possible to implement. I need to use SSO and more specifically OneLogin to authenticate the user via custom UI from my Java standalone application. I know this can be done via Create Session Login Token and then Create session via token One Login API calls. With some parsing I can get the session cookie out of the last call and store it.
Now I need to programmatically hit the API server, which is to be build still and this server somehow needs to validate the session cookie that I am going to send along with request. The key word "Programatically" as in there will be no browser
OneLogin doesn't provide SDK to validate existing session cookie => it would be nice if I could, based on session cookie find out if it is still valid and what is the user name used for this session. If session is invalid API server would return unauthorized.
Is this even possible? Or is it possible in some other way?
Basically One Login is already used in our ecosystem and I have to continue using it
The app that will log user in and get the session cookie may not be the one calling the API server. This could be another java application that would receive the session
I guess what I am looking for is Validate Session equivalent from Open ID Connect API in general API
The session_token that is returned via that API has a short expiry is only intended to be used for making the Create Session request which returns session cookies.
It sounds like OpenId Connect might be the best option for this use case. If you have user credentials then you could use the Resource Owner Password Grant flow to authenticate the user and obtain an id_token.
The id_token is a JWT containing user details can then be verified for authenticity by checking its signature, audience and expiry claims. It can also hold other custom information about the user that may be used by your backend application.

JWT and Session: how JWT should be properly used instead of Session

I am working on a project with PHP and angular. For the user sign in, we're using JWT. Still can't understand why we should use JWT instead of Sessions if each time the user browse a component we need to send the token to server code to check if the user still signed in or not.
Username and password will be sent to server code, where the authentication process will happen, and then generate a token and send it back to angular then save at the local storage.
Any comment on how JWT should be properly used.
EDIT
My question is about the process of checking the JWT when user surf the site and go from component into another.
If you use session for your application... Then while horizontal scaling sharing the session data becomes a burden ....you either need a specialised server .. Jwt are stateless and have no such requirement. It contain following data
Header - information about the signing algorithm, the type of payload (JWT) and so on in JSON format
Signature - well... the signature
Payload - the actual data (or claims if you like) in JSON format
Your JWT already is a proof of your authentication. So you have to send it with each request but you can simplify the authentication logic on server-side.
While on the login you will have to check the credentials you can rely on the JWT's signature and expiryDate. If the signature is still correct the token is valid and you do not have to authenticate anymore.
So regarding your horizontal authentication.
If the called service needs to be authenticated you have to check the JWT for validity on each request (normally works reasonably fast). If there are open api calls you can of course ignore the JWT on server side.
At the end of the day there is no difference to your "session" which will also send some "secret" key which maps your session context. Therefore, it will also be validated.
For some backends you can also use the JWT as your session key to get both worlds involved.
Example:
lets say you have two api roots:
api/secured/*
api/open/*
(Note that the secured and open are only here for demonstrative purposes)
The secured part will contain all the services you want to be authenticated.
The open part can contain insensitive data as well as your login services:
api/open/login -> returns your token
api/open/token/* -> refresh, check re-issue whatever you might need
So now lets say the user accesses your site. You will want to provde an authentication error if he tries to access any api/secured/* URL without a proper JWT.
In this case you can then redirect him to your login and create a token after authenticating him.
Now when he calls an api/secured/* URL your client implementation has to provide the JWT (Cookie, Request header, etc...).
Depending on your framework, language etc. you can now provide an interceptor/filter/handler on server side which will check:
If the JWT is present
if the signature is valid (otherwise the token was faked)
if the JWT is still valid (expiryDate)
Then you can act accordingly.
So to sum up:
There is no need to "authenticate" unless you want to create a new token.
In all other cases it is enough to check the validity of your JWT

Token based authentication in REST APIs

I trying to implement a token based authentication approach:
Every successful login creates new token.
If user selects "keep me logged in" or the user is using a mobile device, the token is persisted in a Redis database without an expiration date. Otherwise, the token will expire in 20 minutes.
Once user is authenticated, the token is checked from each subsequent request in my Redis database.
I'm wondering how I can identify devices. In case of mobile devices, I can use a device identifier. But how can I identify a browser?
Example: The user logs in using Chrome and selects "keep me logged in". A token is generated and persisted with the browser name in Redis. If the user logs in from Firefox, saves the token and "Firefox" in the database. I save the token in Redis whereas token is created on successful authentication. Is it fine to persist only the token and the browser where the token is being used? Or do I need to persist the IP as well?
Additional question: How to avoid attackers to steal the token from a cookie?
How token-based authentication works
In a few words, an authentication scheme based on tokens follow these steps:
The client sends their credentials (username and password) to the server.
The server authenticates the credentials and generates a token.
The server stores the previously generated token in some storage along with the user identifier and an expiration date.
The server sends the generated token to the client.
In every request, the client sends the token to the server.
The server, in each request, extracts the token from the incoming request. With the token, the server looks up the user details to perform authentication and authorization.
If the token is valid, the server accepts the request.
If the token is invalid, the server refuses the request.
The server can provide an endpoint to refresh tokens.
How to send credentials to the server
In a REST applications, each request from client to server must contain all the necessary information to be understood by the server. With it, you are not depending on any session context stored on the server and you do not break the stateless constraint of the REST architecture defined by Roy T. Fielding in his dissertation:
5.1.3 Stateless
[...] each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client. [...]
When accessing protected resources that require authentication, each request must contain all necessary data to be properly authenticated/authorized. It means the authentication will be performed for each request.
Have a look at this quote from the RFC 7235 regarding considerations for new authentication schemes:
5.1.2. Considerations for New Authentication Schemes
There are certain aspects of the HTTP Authentication Framework that
put constraints on how new authentication schemes can work:
HTTP authentication is presumed to be stateless: all of the
information necessary to authenticate a request MUST be provided
in the request, rather than be dependent on the server remembering
prior requests. [...]
And authentication data (credentials) should belong to the standard HTTP Authorization header. From the RFC 7235:
4.2. Authorization
The Authorization header field allows a user agent to authenticate
itself with an origin server -- usually, but not necessarily, after
receiving a 401 (Unauthorized) response. Its value consists of
credentials containing the authentication information of the user
agent for the realm of the resource being requested.
Authorization = credentials
[...]
Please note that the name of this HTTP header is unfortunate because it carries authentication data instead of authorization. Anyways, this is the standard header for sending credentials.
When performing a token based authentication, tokens are your credentials. In this approach, your hard credentials (username and password) are exchanged for a token that is sent in each request.
What a token looks like
An authentication token is a piece of data generated by the server which identifies a user. Basically, tokens can be opaque (which reveals no details other than the value itself, like a random string) or can be self-contained (like JSON Web Token):
Random string: A token can be issued by generating a random string and persisting it to a database with an expiration date and with a user identifier associated to it.
JSON Web Token (JWT): Defined by the RFC 7519, it's a standard method for representing claims securely between two parties. JWT is a self-contained token and enables you to store a user identifier, an expiration date and whatever you want (but don't store passwords) in a payload, which is a JSON encoded as Base64. The payload can be read by the client and the integrity of the token can be easily checked by verifying its signature on the server. You won't need to persist JWT tokens if you don't need to track them. Althought, by persisting the tokens, you will have the possibility of invalidating and revoking the access of them. To keep the track of JWT tokens, instead of persisting the whole token, you could persist the token identifier (the jti claim) and some metadata (the user you issued the token for, the expiration date, etc) if you need. To find some great resources to work with JWT, have a look at http://jwt.io.
Tip: Always consider removing old tokens in order to prevent your database from growing indefinitely.
How to accept a token
You should never accept expired tokens or tokens which were not issued by your application. If you are using JWT, you must check the token signature.
Please note, once you issue a token and give it to your client, you have no control over what the client will do with the token. No control. Seriously.
It's a common practice to check the User-Agent header field to tell which browser is being used to access your API. However, it's worth mention that HTTP headers can be easily spoofed and you should never trust your client. Browsers don't have unique identifier, but you can get a good level of fingerprinting if you want.
I don't know about your security requirements, but you always can try the following in your server to enhance the security of your API:
Check which browser the user was using when the token was issued. If the browser is different in the following requests, just refuse the token.
Get the client remote address (that is, the client IP address) when the token was issued and use a third party API to lookup the client location. If the following requests comes an address from other country, for example, refuse the token. To lookup the location by IP address, you can try free APIs such as MaxMind GeoLite2 or IPInfoDB. Mind that hitting a third party API for each request your API receives is not a good idea and can cause a severe damage to the performance. But you can minimize the impact with a cache, by storing the client remote address and its location. There are a few cache engines available nowadays. To mention a few: Guava, Infinispan, Ehcache and Spring.
When sending sensitive data over the wire, your best friend is HTTPS and it protects your application against the man-in-the-middle attack.
By the way, have I mentioned you should never trust your client?
Once server is receives the request from the client, it contains the User-Agent. This attribute will help us to identify the client.
Please refer this link: How do I detect what browser is used to access my site?

What should happen to when user changes username in Oauth2

Am pretty new to Oauth2 and I wondering what should happen in a scenario where a user changes the username used to authorize a client.
Should all access tokens expire after change is successful requesting the client to a new access code?
or
The access tokens are to be updated with the new username by the authentication server?
In normal cases, username of a user and the unique ID of the user are different. If an access token is associated with the unique ID (not with username), you don't have to invalidate or update access tokens even if username is changed.
Otherwise, if you associate access tokens with username (not with the unique ID), when username is changed, you should invalidate access tokens or update access tokens with the new username.
The OAuth spec doesn't specify what should happen -- one the user passes authentication and gets a token, they have an active authorization "session" as long as that token is valid.
You can invalidate tokens, and authorization sessions, as you like, though. So as a matter of policy, if you want to invalidate their tokens when there's a change to the account, then you are free to do that.
Just remember to invalidate both access tokens and refresh tokens for the user, or else they might just use their refresh token to start over with a access token.

Resources