Persisting the refresh token of the Spring OAuth2RestTemplate - java

I have a mobile application that uses my Spring Boot backend for things like authentication and accessing data. A part of the Spring Boot application accesses data from a resource server using OAuth2. I stumbled across an oauth2 client library for Spring that does its magic and everything just works out of the box.
As I'm trying to figure out how this library does its work, I can't seem to find an answer to the way it handles refresh tokens. I'm aware that the oauth2client is bound to a session for each user but what happens when the session ends? Wouldn't the access and refresh tokens get lost?
I was looking for ways to persist the refresh token for each user in my database but I didn't find any support for that in the library. This leaves me wondering if I have to implement this myself or if there's even a need to do so.
Any advice is appreciated!

Basically OAuth2 architecture is used for 3rd-party authentication and authorization. In this mechanism the credentials remains secured and aren't passed on while everything works upon tokens! But you can use it to work implicitly for your own authentication too.
In your case first when you hit "/oauth/token"(default endpoint) along with the client-secret and client-Id and rest of the user credentials the algo checks for the user details in the DB and matches the secret and Id present in the header of the request. If everything goes fine it'll generate a bearer type - access and refresh token and will store these tokens in different collections in the database.This particular user is mapped to these tokens and can access /api's using them only.No user creds are required. You can use MongoTokenStore if you're using MongoDb for storing and accessing stored tokens.
Next you have to configure WebSecurity/AuthorizationServer/ResourceServer for checking endpoints and header tokens tokens, authentication and authorizaton of users and providing valid tokens access to the resource respectively.
Lastly when you have a valid access token and hit an api with a correct header request the server grants you permission to access the resource!
This is the basic functionality of the OAuth2.0.
Normally Access Tokens have a shorter lifetime while refresh tokens have comparitively larger lifetime. Once Access Token gets expired a new Access Token can be generated using the Refresh Tokens. If the Refresh Tokens gets expired then you have to hit the "/oauth/token" api again,complete the flow cycle and generate tokens again.After expiry when you hit an api with existing access token they are removed from the collection. This is the default architecture of this mechanism, rest you can make custom classes and modify its functionality according to your needs! This architecture is quite secure and is a good practise.
Screenshot Flow Diagram
Check this post from digitalocean.
Edits ----
Personally I used MongoDB where I made two collections -
AuthAccessTokens and AuthRefreshTokens namely where these two were
stored. Access Token object has an Id of associated RefreshToken
which helps to map these two together. Rest custom additional Info.
can also be added using TokenEnhancer. Therefore tokens will always
be present in the DB unless expired. And in layman's terms if you
are just focussing on Backend stuff you can always check for your
access tokens by hitting "/oauth/token" with correct user creds and
it will return the assigned token by fetching it from the DB, else
if you're developing full stack after generating the tokens on first
step just store them on client end either in browser's local storage
or app. And if you want to deliberately end the session like for
example in Logout just remove these tokens from their respective
collections.

Related

How to expire already generated existing JWT token using Java? [duplicate]

I am using Spring Security OAuth2 and JWT tokens. My question is: How can I revoke a JWT token?
As mentioned here
http://projects.spring.io/spring-security-oauth/docs/oauth2.html, revocation is done by refresh token. But it does not seem to work.
In general the easiest answer would be to say that you cannot revoke a JWT token, but that's simply not true. The honest answer is that the cost of supporting JWT revocation is sufficiently big for not being worth most of the times or plainly reconsider an alternative to JWT.
Having said that, in some scenarios you might need both JWT and immediate token revocation so lets go through what it would take, but first we'll cover some concepts.
JWT (Learn JSON Web Tokens) just specifies a token format, this revocation problem would also apply to any format used in what's usually known as a self-contained or by-value token. I like the latter terminology, because it makes a good contrast with by-reference tokens.
by-value token - associated information, including token lifetime, is contained in the token itself and the information can be verified as originating from a trusted source (digital signatures to the rescue)
by-reference token - associated information is kept on server-side storage that is then obtained using the token value as the key; being server-side storage the associated information is implicitly trusted
Before the JWT Big Bang we already dealt with tokens in our authentication systems; it was common for an application to create a session identifier upon user login that would then be used so that the user did not had to repeat the login process each time. These session identifiers were used as key indexes for server-side storage and if this sounds similar to something you recently read, you're right, this indeed classifies as a by-reference token.
Using the same analogy, understanding revocation for by-reference tokens is trivial; we just delete the server-side storage mapped to that key and the next time the key is provided it will be invalid.
For by-value tokens we just need to implement the opposite. When you request the revocation of the token you store something that allows you to uniquely identify that token so that next time you receive it you can additionally check if it was revoked. If you're already thinking that something like this will not scale, have in mind that you only need to store the data until the time the token would expire and in most cases you could probably just store an hash of the token so it would always be something of a known size.
As a last note and to center this on OAuth 2.0, the revocation of by-value access tokens is currently not standardized. Nonetheless, the OAuth 2.0 Token revocation specifically states that it can still be achieved as long as both the authorization server and resource server agree to a custom way of handling this:
In the former case (self-contained tokens), some (currently non-standardized) backend interaction between the authorization server and the resource server may be used when immediate access token revocation is desired.
If you control both the authorization server and resource server this is very easy to achieve. On the other hand if you delegate the authorization server role to a cloud provider like Auth0 or a third-party component like Spring OAuth 2.0 you most likely need to approach things differently as you'll probably only get what's already standardized.
An interesting reference
This article explain a another way to do that: Blacklist JWT
It contains some interesting pratices and pattern followed by RFC7523
The JWT cann't be revoked.
But here is the a alternative solution called as JWT old for new exchange schema.
Because we can’t invalidate the issued token before expire time, we always use short-time token, such as 30 minute.
When the token expired, we use the old token exchange a new token. The critical point is one old token can exchange one new token only.
In center auth server, we maintain a table like this:
table auth_tokens(
user_id,
jwt_hash,
expire
)
user_id contained in JWT string.
jwt_hash is a hash value of whole JWT string,Such as SHA256.
expire field is optional.
The following is work flow:
User request the login API with username and password, the auth server issue one token, and register the token ( add one row in the table. )
When the token expired, user request the exchange API with the old token. Firstly the auth server validate the old token as normal except expire checking, then create the token hash value, then lookup above table by user id:
If found record and user_id and jwt_hash is match, then issue new token and update the table.
If found record, but user_id and jwt_hash is not match , it means someone has use the token exchanged new token before. The token be hacked, delete records by user_id and response with alert information.
if not found record, user need login again or only input password.
when use changed the password or login out, delete record by user id.
To use token continuously ,both legal user and hacker need exchange new token continuously, but only one can succeed, when one fails, both need to login again at next exchange time.
So if hacker got the token, it can be used for a short time, but can't exchange for a new one if a legal user exchanged new one next time, because the token validity period is short. It is more secure this way.
If there is no hacker, normal user also need exchange new token periodically ,such as every 30 minutes, this is just like login automatically. The extra load is not high and we can adjust expire time for our application.
source: http://www.jianshu.com/p/b11accc40ba7
This doesn't exactly answer you question in regards to the Spring framework, but here's an article that talks about why if you need the ability to revoke JWT's, you might not want to go with JWT's in the first place, and instead use regular, opaque Bearer tokens.
https://www.dinochiesa.net/?p=1388
One way to revoke a JWT is by leveraging a distributed event system that notifies services when refresh tokens have been revoked. The identity provider broadcasts an event when a refresh token is revoked and other backends/services listen for the event. When an event is received the backends/services update a local cache that maintains a set of users whose refresh tokens have been revoked.
This cache is then checked whenever a JWT is verified to determine if the JWT should be revoked or not. This is all based on the duration of JWTs and expiration instant of individual JWTs.
This article, Revoking JWTs, illustrates this concept and has a sample app on Github.
For Googlers:
If you implement pure stateless authentication there is no way to revoke the token as the token itself is the sole source of truth
If you save a list of revoked token IDs on the server and check every request against the list, then it is essentially a variant of stateful authentication
OAuth2 providers like Cognito provides a way to "sign out" a user, however, it only really revokes refresh token, which is usually long-lived and could be used multiple times to generate new access tokens thus has to be revoked; the existing access tokens are still valid until they expire
What about storing the JWT token and referencing it to the user in the database? By extending the Guards/Security Systems in your backend application with an additional DB join after performing the JWT comparison, you would be able to practically 'revoke' it by removing or soft-deleting it from the DB.
In general, the answer about tokens by reference vs. tokens by value has nailed it. For those that stumble upon this space in future.
How to implement revocation on RS side:
TL;DR:
Take a cache or db that is visible to all your backend service instances that are verifying tokens. When a new token arrives for revocation, if it's a valid one, (i.e. verifies against your jwt verification algo), take the exp and jti claims, and save jti to cache until exp is reached. Then expire jti in cache once unixNow becomes > exp.
Then on authorization on other endpoints, you check everytime if a given jti is matching something in this cache, and if yes, you error with 403 saying token revoked. Once it expires, regular Token Expired error kicks in from your verification algo.
P.S. By saving only jti in cache, you make this data useless to anyone since it's just a unique token identifier.
The best solution for JWT revocation, is short exp window, refresh and keeping issued JWT tokens in a shared nearline cache. With Redis for example, this is particularly easy as you can set the cache key as the token itself (or a hash of the token), and specify expiry so that the tokens get automatically evicted.
I found one way of resolving the issue, How to expire already generated existing JWT token using Java?
In this case, we need to use any DB or in-memory where,
Step 1: As soon as the token is generated for the first time for a user, store it in a db with the token and it's "issuedAt()" time.
I stored it in DB in this JSON format,
Ex: {"username" : "username",
"token" : "token",
"issuedAt" : "issuedAt" }
Step 2: Once you get a web service request for the same user with a token to validate, fetch "issuedAt()" timestamp from the token and compare it with stored(DB/in-memory) issued timestamp.
Step 3: If stored issued timestamp is new (using after()/before() method) then return that the token is invalid (in this case we are not actually expiring the token but we are stop giving access on that token).
This is how I resolved the issue.

restapi authentication without OAuth library

I have working REST API and would like to authenticate users by providing tokens with expiry dates but without using OAuth library.
Here is what I'm thinking.
Can I create two methods, first will be having three parameters
Username, Password and Master token
And once its authenticate, it will produce one temporary token with some expiry date. This I will store into in database entry and will return to the client as well.
So when I will make second request with URL having token generated by first method, it will check into second method having parameter "token" where it will match with database entry, and if it agrees data will be exposed.
Can I do it in that way ? Does it makes sense for having authentication in this way ? If no please share your comments.

JWT implementation with out Oauth

I want to create an applicacion with angular js and REST services with JWT and out oauth. I want to know how to implement refresh token or the way to generate a token for a week for example, what I have to do?
The architecture is: Java , REST, Angular.js and Bootstrap
user send login and password
the server return token
app user token for access to rest api
rest return result
It’s definitely possible to implement a token authentication scheme without implementing the entire OAuth framework. Your solution would need to have the following characteristics:
It needs to exchange credentials for access tokens and refresh tokens (password grant flow)
The tokens you create should be signed with a key that is private to the server
Authenticate requests that present an access token. It needs to verify access tokens by asserting that the signature is valid and the token is not expired
It needs to issue new access tokens if a valid refresh token is presented (refresh token grant flow)
Access tokens should have a shorter lifetime then refresh tokens
It should reject refresh tokens if the refresh token has been revoked (you need to maintain a blacklist of revoked tokens.
It should do extra checks when the refresh token is being used to get a new access token: is the account still enabled? Or any other check that is relevant to your business logic.
An open-source solution is Kong.
If you’d like to offload this infrastructure, you can consider a product like Stormpath which can add the Oauth2 token framework to an existing application via our Java Integrations. Disclaimer: I work at Stormpath and I think that access tokens and refresh tokens are the best!

Token based authentication for REST service: where to store generated token on server-side?

I'm trying to implement token authentication for a REST service based on Spring MVC.
I'm followiong this SO answer: https://stackoverflow.com/a/10864088/1061499 as guideline, but now I need to understand some server-side detail.
When an user is successfully authenticated (first time via username + password) I return a token that stores some information.
When the same user sent his token in a request header, I need to identify the associated user and define if is "session" is still alive.
So the way are basically two:
encrypt the token with an algorithm (which one?) I can also use to decrypt on server side and extract user information
store token-user association info in application DB also storing session info.
Most suggest the first solution, without storing any info about authentication in DB, but this solution seems to me less secure.
Any suggestion?

How can I direct-login by using Google-Drive-SDK in JAVA?

I want to get users' access_token by using Google Drive SDK in JAVA.
I completed to get access_token when user log-in first time. But, I really want to direct-login. I know access_token be expired, so 'refreshToken' can be my solution. But refreshToken is always 'null'. How can I perform direct-login? Many advices welcome.
You need to separate "login" from "access drive". Once your application has an access token for a given user/scope, it can access Drive on behalf of the user. There are two (main) ways your application can obtain an access token.
It can request access which will involve the user being logged in to grant access.
In step 1, it can request "offline" access, in which case it will be given an access token and a refresh token. It can subsequently use the refresh token to request more access tokens without the user being present.
I suspect that you want to do option 2. This is described quite well at https://developers.google.com/accounts/docs/OAuth2WebServer#offline
If you have tried this and you having problems, please paste your code and the http trace so we can look at the problem with you.

Categories