Best way to authenticate access token for every Rest API request - java

In general what is the best way to authenticate the access token in interceptors, If the access token information is stored in HashMap for each and every user, the hashmap grows as the number of users increases.
If we query database for every api request, it increases load on database.
Please mention if there are any other techniques you know.
And also what other things I need to consider while authenticating the access token for every request. What are the pre-processing and post-processing steps while authenticating access token.
Thanks in Advance.

Check out Json Web tokens. Using them allows your server to become stateless (not saving any sessions on memory).
Its concept is to pass a digital signed token, for every request, and checking that the signature is correct for integrity.
Json Web Encryption also can encrypt sensitive data along the token (such as user id).
This makes it very easy to work on a distributed environment
Check out this website: https://jwt.io/. There are some implementations in java and plenty of code examples to start with.

Some words about authentication with tokens
Once you are using JAX-RS, have a look at this answer that I wrote a while ago.
Your tokens can be any randon string persisted to some storage. On the other hand, JWT tokens allow you to have stateless authentication (no persistence). If you need to track the JWT tokens (to revoke them, for example), you must persist at least their identifier (the jti claim). A HashMap shouldn't be used to "persist" tokens (that's not a real persistence and it won't scale). Instead, consider a database like Redis.
To generate and parse JWT tokens, have a look this library created by Stormpath and maintained by a community of contributors. I currently use it in some applications and I can say with confidence that it works just fine and it's easy to use.
Keep reading for more details about the authentication process.
Authentication with tokens at a glance
In a few words, a token-based authentication 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.
Using JAX-RS to implement authentication based on tokens
The authentication starts when the server receives the hard credentials (username and password) of a user and exchanges them with a token that the client must send in each request:
#Path("/authentication")
public class AuthenticationResource {
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response authenticateUser(Credentials credentials) {
try {
// Authenticate the user using the credentials provided
String username = credentials.getUsername();
String password = credentials.getPassword();
authenticate(username, password);
// Issue a token for the user
String token = issueToken(username);
// Return the token on the response
return Response.ok(token).build();
} catch (Exception e) {
return Response.status(Response.Status.UNAUTHORIZED).build();
}
}
private void authenticate(String username, String password) throws Exception {
// Authenticate against a database, LDAP, file or whatever
// Throw an Exception if the credentials are invalid
}
private String issueToken(String username) {
// Issue a token (can be a random String persisted to a database or a JWT token)
// The issued token must be associated to a user
// Return the issued token
}
}
A filter will be used to extract the token from the HTTP request and validate it:
#Provider
#Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
// Get the HTTP Authorization header from the request
String authorizationHeader =
requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
// Check if the HTTP Authorization header is present and formatted correctly
if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
throw new NotAuthorizedException("Authorization header must be provided");
}
// Extract the token from the HTTP Authorization header
String token = authorizationHeader.substring("Bearer".length()).trim();
try {
// Validate the token
validateToken(token);
} catch (Exception e) {
requestContext.abortWith(
Response.status(Response.Status.UNAUTHORIZED).build());
}
}
private void validateToken(String token) throws Exception {
// Check if it was issued by the server and if it's not expired
// Throw an Exception if the token is invalid
}
}
For further details, have a look at this answer.
JSON Web Token
JSON Web Token (JWT) is defined by the RFC 7519 and I think it fits really well for your needs.
It's a standard method for representing claims securely between two parties (in this situation, client and server). 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.
To find some great resources to work with JWT, have a look at http://jwt.io.
And remember: when sending sensitive data over the wire, your best friend is HTTPS. It protects your application against the man-in-the-middle attack.
Tracking the tokens
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.
There are many databases where you can persist your tokens. Depending on your requirements, you can explore different solutions such as relational databases, key-value stores or document stores.
Your application can provide some functionality to revoke the tokens, but always consider revoking the tokens when the users change their password. When persisting tokens, always consider removing the old ones in order to prevent your database from growing indefinitely.

You can combine both HashMap and database. In your case, HashMap can be used as a cache. The first time user was authenticated, access token information of this user should store to HashMap. The next APIs, we will check if the access token is exist in HashMap. If it exists, we use it to authenticate, if not we will query from database and store it to HashMap.
You need to expire access tokens in HashMap that was not used for a duration.

Related

Get access token using Spring Security with a specific use-case

Is this use-case supported for Spring Security 5, or something else, where we don't have to reinvent the wheel? Thoughts on how to (re)implement this better?
Details are as follows. 3rd party vendor supplied endpoints. We pull info from upstream source then forward to the downstream vendor. Only 2 APIs are required:
Request Access Token
Save Info
Both are actually being called via a gateway. We've been given specifics:
(A)
The token request requires Basic Auth (standard header - usual base64 encoded). Gateway User and Gateway Password are provided.
Credentials for request token are provided to us:
Grant Type = password
Consumer Id
Consumer Secret
Account User
Account Password
It responds with an access token and few other details we don't really care about and of zero value to our use-case.
There is no expires_in info in the response. But I've tested it multiple times to know it does expire. Not sure how long right now, I could do more tests to determine that.
(B)
The save request requires a different custom header for the same Gateway User / Password, then a Bearer Authorization header in the call to the Save Info API.
Right now, all implementations for above are using RestTemplate. Working fine already. But a token is requested for each save which is costly. Before writing any caching, or some other logic to wait XY minutes before another token request is made, I would appreciate any other options which may already be possibly handled via Spring-specific libraries or further advise on how to handle this scenario.
Apologies if this is not the right place to ask this, or it has already been asked before. Been searching for a similar use-case but can't seem to find one.
Thanks.
Try any one of the option
You can use OAuth2ClientContext which stores your access token.
final OAuth2RestTemplate restTemplate=new OAuth2RestTemplate(resourceDetails, clientContext);
You can create session & store your token & user details inside it.
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(user, null,null);
SecurityContextHolder.getContext().setAuthentication(authToken);
from option 1 Or option 2 you can then fetch existing token for each request at your Filter e.g. PRE_AUTH_FILTER
Then check if token expired - if yes request new token Or call refresh token
Check Oauth2 expires_in in below :-
https://www.rfc-editor.org/rfc/rfc6749?

How to prevent Rest web-service Authentication with stolen Token

As we know Rest services are stateless, General strategies to authenticate is using a token based authentication.
In login service it takes credentials which returns a token.
This token might be set in client cookies, and all subsequent requests uses this token to be validated and process new request if token is valid.
Now my question is how one can validate the token ? If someone has stolen the token and tries to access rest services with stolen token by just editing cookies then how can it be identified and restricted ?
We can never know if the token is fetched by valid user and same user is trying to access subsequent request. but what are the possible ways to make it more hard, like to verify if the request has came from same source ?
One general suggestion is to set aging for token/cookies, but it still not helpful till the age of that token/cookies.
Any suggestions would be appreciated.
I don’t believe there are any 100% fool proof methods of preventing access with stolen user tokens. How do you even know that the token is stolen in the first place? But from the top of my head you might want to consider following:
Accessing a REST service with the same token but a different user agent is suspicious. This can be recognized with the value of the User-Agent header. You might want to consider dropping such requests.
What if the IP address changes but the token is still the same? Well, maybe someone is using a load balancer and accesses the network over different IP addresses? Or he accessed a VPN with the same token/cookie as before? If you have no compunction dropping such requests, you might level up the security by checking the source IP address too.
In case of – say – JWT tokens, you will need a bit of infrastructure to handle the blacklisting. Follow this.
My current understand of the "most secure" approach to authorizing requests in the browser is to require validation of an HttpOnly SameSite cookie AND HTTP header (e.g. Authorization or X-CSRF-Token) in combination.
For example, when issuing the JWT to a browser, send the JWT signature in an HttpOnly SameSite cookie, and send the body (without signature) to the client to store in localStorage and submit in the Authorization header. When authorizing a request, combine the two back into the complete JWT and validate it as normal after that.
Alternatively, you can generate two JWTs with a field to distinguish them (e.g. the client one has "browser" in it, the cookie has "cookie") and require that both are valid and both identify the same user. One is sent in the Authorization header and stored in localStorage and the other uses the SameSite HttpOnly cookie.
Another popular approach is to store a CSRF token in a field in the JWT, and put the JWT into a cookie and require the client to send a matching token in a header (e.g. X-CSRF-Token).
All of the solutions effectively prevent XSS and CSRF attacks: XSS cannot retrieve the HttpOnly cookie, and CSRF does not include the HTTP header, so this blocks both attacks.
Note that you probably only want to apply this rule for requests from web browsers. For server-to-server communication, requests are not subject to CSRF and XSS attacks.
After struggling through various approach We found a solution explained below:
We store token (encrypted) in cookies on login request and for each subsequent request this cookie gets validated.
The problem was if someone replace the token in cookie with another valid token, as cookies are maintained by client browser.
Solution :-> Though token values were encrypted, it was representing only one value, So if one replace whole encrypted value with another valid encrypted value it can be hacked.
So to solve this we have added another cookie which was combination of multiple values.
e.g.
Cookie 1 -> encrypted token
Cookie 2 -> An encrypted object containing information like username+ some other user context details+token
So in case of Cookie 1, it was easy to replace with another encrypted value as it was representing only one token though it was encrypted.
But in case of Cookie 2, it was containing object with multiple values, so only token value can not be modified, encrypted and set back in same cookie.
Before authentication We are doing decryption whole cookie 2, fetch token part from it and validate the token part of it against cookie 1.
That has solved our problem !!
Thanks all for your time and guidance.
You can use jwt is an Internet standard for creating JSON-based access tokens that assert some number of claims. For example, a server could generate a token that has the claim "logged in as admin" and provide that to a client. The client could then use that token to prove that it is logged in as admin .
How it's working ?
First it's contain private key generated by developer :
let us have this key :sfcqw#sav%$#fvcxv*s_s515 and this one called private key , and we also have a public key this the public key generated depended on user data and private key and it's impossible to know what is contain if you don't know the private key .
to more explain :
public key :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.plpJkAcgrgCIsoRyV2kjGsvWF6OsXU1mD785OSWTH4o
we have the above key generated by our private key : sfcqw#sav%$#fvcxv*s_s515
To be more clear going to this website : https://jwt.io/ and try to past the public key without put secrite key like picture and you will understand everything .
To me, there was no way to prevent the access from being stolen JWT token except
setting a short timeout for the token
more secured at the HTTP request level by only allowing specific `User-Agent. See more
more secured at the HTTP request level by customizing the header key for the organization, e.g My-X-Auth = Bearer <token> instead of Authorization= Bearer <token>
more secured at the HTTP request level by restricting trusted urls/domains, e.g X-Content-Security-Policy. See more

How to access the JWT Token and then process the request?

I have been given a spring boot web api project. There is a flutter application that will send a jwt token as a request and the api has to get the "ticket" value out of the payload and then check the database and send the required data. I am totally a newbie in this field but I have no choice rather than complete it.
I wanted to make the matter easy by just accepting the token and try to decode that and get the "ticket" value out. But I was unable to do so as I am unable to get the token in the very first place.
The authentication is being done by some other api and that is providing the jwt token to the flutter application. Then the flutter application will send that token in any request to my api. I have a sample database with the data required and will have to resolve the request using "ticket" (which is acting as a username) from the database and will provide the data. I don't have to perform any authentication part - I just have to extract the token from the request - decode that and get the "ticket" value and have to search the database and provide the data.
token : eyJhbGciOiJIUzUxMiJ9.eyJ0aWNrZXQiOiJzdmxhZGFAZ21haWwuY29tIiwic2NvcGVzIjpbIlJPTEVfQURNSU4iLCJST0xFX1BSRU1JVU1fTUVNQkVSIl0sImlzcyI6Imh0dHA6Ly9zdmxhZGEuY29tIiwiaWF0IjoxNDcyMzkwMDY1LCJleHAiOjE0NzIzOTA5NjV9.uaHqDrTNnn5TAljcWRYac9ifJJv5NR5cdn7id2xVCAKLD37_pY62jPlk70XtwqgSar03n2qEgzWyTdWXRcnsgQ
reuest : localhost:8080/persons?access_token=eyJhbGciOiJIUzUxMiJ9.eyJ0aWNrZXQiOiJzdmxhZGFAZ21haWwuY29tIiwic2NvcGVzIjpbIlJPTEVfQURNSU4iLCJST0xFX1BSRU1JVU1fTUVNQkVSIl0sImlzcyI6Imh0dHA6Ly9zdmxhZGEuY29tIiwiaWF0IjoxNDcyMzkwMDY1LCJleHAiOjE0NzIzOTA5NjV9.uaHqDrTNnn5TAljcWRYac9ifJJv5NR5cdn7id2xVCAKLD37_pY62jPlk70XtwqgSar03n2qEgzWyTdWXRcnsgQ
The code is not necessary I just want to learn how it works. There are many videos in YouTube but they all are concentrated on the authentication which I don't have to perform and none is showing how the request from the application is to be handled. Any resources will also be a great help. Thank You.
reuest : localhost:8080/persons?access_token=eyJhbGciOiJIUzUxMiJ9.eyJ0aWNrZXQiOiJzdmxhZGFAZ21haWwuY29tIiwic2NvcGVzIjpbIlJPTEVfQURNSU4iLCJST0xFX1BSRU1JVU1fTUVNQkVSIl0sImlzcyI6Imh0dHA6Ly9zdmxhZGEuY29tIiwiaWF0IjoxNDcyMzkwMDY1LCJleHAiOjE0NzIzOTA5NjV9.uaHqDrTNnn5TAljcWRYac9ifJJv5NR5cdn7id2xVCAKLD37_pY62jPlk70XtwqgSar03n2qEgzWyTdWXRcnsgQ
From the above request, you can design the controller like as follows :
#GetMapping("/persons")
public ResponseEntity loadPersons(#RequestParam("access_token") String access_token,HttpServletRequest request){
//Here you can play with the token now
//you can also get the token if it is coming with request header as follows :
String token =request.getHeader("access_token");//replace with the specific key
}
e.g.
public boolean isValidJWTToken(String jwtToken){
boolean isValid = true;
try {
Jwts.parser().setSigningKey(generateKey()).parseClaimsJws(jwtToken);
} catch (Exception e) {
isValid = false;
}
return isValid;
}
private Key generateKey() {
byte[] keyBytes=environment.getProperty("auth.jwt.secret.key").getBytes();
return new SecretKeySpec(keyBytes, 0,keyBytes.length,environment.getProperty("auth.jwt.secret.algo"));
}
TheJWT Token has 3 parts .
1. HEADER:ALGORITHM & TOKEN TYPE
2. PAYLOAD:DATA
3. SIGNATURE
All the above 3 parts are your business driven. So you can better know which is the algo used for encode . Accordingly, you can do decode.

JWT authentication: How to implement logout?

I implemented JWT authentication for my Spring boot app. Overally, it works like this:
Client sends username, password to the login endpoint.
Server checks if the provided credentials are valid.
If no, it would return an error
If yes, it would return a token, that token actually includes
Client sends that token with every future request
The question is, how should we implement logout ?
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
class TokenAuthenticationService {
static final long EXPIRATIONTIME = 864_000_000; // 10 days
static final String SECRET = "ThisIsASecret";
static final String TOKEN_PREFIX = "Bearer";
static final String HEADER_STRING = "Authorization";
static void addAuthentication(HttpServletResponse res, String username) {
String JWT = Jwts
.builder()
.setSubject(username)
.setExpiration(
new Date(System.currentTimeMillis() + EXPIRATIONTIME))
.signWith(SignatureAlgorithm.HS512, SECRET).compact();
res.addHeader(HEADER_STRING, TOKEN_PREFIX + " " + JWT);
}
static Authentication getAuthentication(HttpServletRequest request, UserDetailsService customUserDetailsService) {
String token = request.getHeader(HEADER_STRING);
if (token != null) {
// parse the token.
Claims claims = Jwts.parser().setSigningKey(SECRET)
.parseClaimsJws(token.replace(TOKEN_PREFIX, "")).getBody();
String userName = claims.getSubject();
Date expirationTime = claims.getExpiration();
if (expirationTime.compareTo(new Date()) < 0) {
return null;
}
UserDetails user = customUserDetailsService.loadUserByUsername(userName);
return user != null ? new UsernamePasswordAuthenticationToken(user.getUsername(),
user.getPassword(), user.getAuthorities()) : null;
}
return null;
}
}
addAuthentication is used by the JWTLoginFilter class to send the authentication code when logging in, 'getAuthenticationis used by theJWTAuthenticationFilter` that filter all requests to the end points.
What is the best practice here ?
I don't think there is a best practice here. I guess it depends on the application you're building and it's requirements.
The benefit of JWT is that they're stateless. You don't need to query the database to validate the token. This is good when you wish to reduce the load on your database but bad when you want to invalidate an existing non-expired token.
Possible solutions:
Store JWT in the database. You can check which tokens are valid and which ones are revoked but this defeats the purpose of using JWT at all in my opinion.
Delete token from the client. This would stop the client from being able to make authenticated requests but if the token is still valid and somebody else has access to it, the token could still be used. This leads me to my next point.
Short token lifetime. Let the tokens expire quickly. Depending on the application, it could be several minutes or half an hour. When the client deletes its token, there's a short window of time where it can still be used. Deleting the token from the client and having short token lifetimes would not require major modifications on the back-end. But short token lifetimes would mean that the user is constantly being logged out because the token has expired.
Rotate tokens. Maybe introduce a concept of refresh tokens. When the user logs in, provide them with a JWT and a refresh token. Store the refresh token in a database. For authenticated requests, the client can use the JWT but when the token expires (or is about to expire), let the client make a request with the refresh token in exchange for a new JWT. This way you would only have to hit the database when a user logs in or asks for a new JWT. When the user logs out, you would need to invalidate the stored refresh token. Otherwise somebody listening in on the connection could still get new JWTs even though the user had logged out.
Create a JWT blacklist. Depending on the expiration time, when the client deletes its token, it might still be valid for some time. If the token lifetime is short, it might not be an issue, but if you still wish that the token is invalidated immediately, you could create a token blacklist. When the back-end receives a logout request, take the JWT from the request and store it in an in-memory database. For each authenticated request you would need to check your in-memory database to see if the token has been invalidated. To keep the search space small, you could remove tokens from the blacklist which have already expired.
I don't know what's best practice, but in a system whose internals I have seen, there is a central authentication manager which knows all the currently valid authentication tokens, so logging out would simply consist of removing the token from the collection of valid tokens.
So, next time the authentication manager is asked whether the token is valid, it would respond with a "no".
1) Simply remove the token from the client
2) Create a token blacklist
3) Just keep token expiry times short and rotate them often
Please have a look at Invalidating JSON Web Tokens
Invalidating JSON Web Tokens

Best practices for managing auth token

I am writing a REST client in Java using the HttpCLient , the REST API that I access needs an auth token for every REST action. This token is valid for 24 hours.
The way I am handling this now is calling a "getAuth()" method everytime I need to make a REST call which seems like an overhead on the auth server.
How can I conveniently store this auth token and manage its life cycle?
Are there any documented best practices?
I thought of the following solution
public class MySession {
String user;
String pass;
public MySession(String user, String pass) {
this.user = user;
this.pass = pass;
}
public getAuth() {
//user user, pass to get auth token
}
}
and then pass the sessions object to any class that nees the token. If the token is expired, just call this method again
For brevity I'll assuming you're calling an endpoint that you can't change. How you should implement will heavily depend on whether the token is app or user based (one token for all users on a shared app instance or one token per user).
If it's one auth token for the entire app:
Store it in memory along with a time-to-live timestamp (or alternatively catch the token expired error, request a new token and retry the original request), refresh it if it doesn't exist/is expired
If you're concerned about re-requesting API tokens after an application restart also store it in the database and load it at startup if it exists
If it's one token per user:
Store it in your user session, it's exactly what sessions are used for, if you're authing users then they'll have a session and the overhead is already there
If you don't want to re-request a token everytime they login store their current token in the DB and and load it into their session when they login
I'm assuming you are using OAuth for authorization. Whether you are using JWT or other tokens is irrelevant to this situation.
When performing authorization you will be issued an access_token with an expiration and, depending on the grant type you are requesting (Client credentials, Authorization code, Implicit, Resource owner), a refresh_token.
The client should keep the access_token and the expiration. The refresh_token, if issued, must be kept secret (beware of using the correct grant for your use case).
In subsequent calls, your client should not request new tokens on each call, it should use the stored access_token.
Once the API starts returning 401 Unauthorized, the access_token has probably expired. Your client should try to refresh the access_token using the refresh_token if you got one.
If you have no refresh_token or the refresh request also failed, because the refresh_token is no longer valid, you can perform a new authorization flow.
You can use the expiration time as a clue to know when to get a new access_token either through refresh or through a new full authorization flow. This will avoid the 401 Unauthorized. In any case, your client should have a fall back policy when this response is received after having used a valid access_token for some calls.
You can create a manager and store the auth-cookie during login in thread local like the code below. You can get the cookie from getAuth() as long as the thread lives.
public class Manager {
private static final ThreadLocal<String> SECURITY_CONTEXT = new ThreadLocal<>();
public static void setAuth(String auth) {
SECURITY_CONTEXT.set(auth);
}
public static String getAuth() {
return SECURITY_CONTEXT.get();
}
public static void clear(){
SECURITY_CONTEXT.remove();
}
}
I suggest you to use the following scenario:
1) First, call auth(username, password) rest api to get the auth token.
If the given credentials are okay then just send back the auth cookie to the client with HTTP 200 response code.
2) Then, you can call protected rest apis. You need to send auth cookie with your request each time.
3) Servlet filter (or something similar) checks each incoming request and validates the token. If the token is valid then the request goes forward to the rest method, if not you need to generate an http 401/403 response.
I suggest you not to write your own authentication layer. Instead of install and use an existing one. I suggest you OpenAM. It is a superb open source access management system.
I also suggest you not to open session on the server side for authentication purpose. If you have 10 clients then 10 sessions needs to be managed by server. It is not a big issue. But if you have 100 or 1000 or millions different clients than you need more memory to store sessions on the server.
If you are worried about too many hits to the database, then i'm assuming there is a lot of web activity.
I would not recommend using Session in your case, but rather store the token in a cookie on the client.
In a high traffic environment(which i'm assuming yours is), the use of Session can consume a lot of server memory, and scalability can be a concern as well, having to keep sessions in sync within a cluster.
As #Cássio Mazzochi Molin also mentioned, you can use an in-memory cache to store any user specific data and tokens. This will reduce the hits to the database, and also allow you to scale the application easier, when the need arises.
The de-facto standard is not implementing your own solution (basic rule in security: don't implement your own stuff!), but use the de-facto standard solution, namely JSON Web Tokens.
Documentation on the site, but the basic idea is, that you only need to store one value (the server's private key), and then you can verify every claim, issued originally by the server (which will in your case contain an expiry time).
You should use JsonWebToken (JWT in short) for this kind of stuff. JWT has build in support to set the expiration date. There are plenty of libraries to use this method and you can read more here
There are currenlty 4 java implementations and all of them can check if the token is still valid (exp check)
So if I'm understanding correctly you are using the same token for all of your requests (which means as long as your app is up and running and you refreshing the tokens, you should be ok. I literally had the same problem and this is how I've resolved it. I have a singleton class, which is initialized at the app start for once and refreshes the token when its invalidated. I'm using C#, Asp.NET MVC5 and AutoFac for DI, but I'm sure you can do the same with Java and Spring.
Updating property of a singleton with Thread Safety
Use json web tokens , to exchange information between two clients. The token will only alive for the 24 hours period, after that time all consequent calls in the header will be rejected.
Auth Token for each request is correct approach, Consider auth server scaling for performance issue.
On first successful authentication (username and password), generate private public keypair. Store private key as Session Security Token (SST) and send public key as Public Security Client Key (PSCK) to client
In all request other than login (or authentication) client will send PSCK to protect theft of username and password and server can verify PSCK for expiry internally at regular intervals saving processing time.
If system is having performance issue on authentication side, setup seperate auth server with scalability.
No token or password to be cached, exchanged unencrypted and send outside security zone. Do not post using URL parameters.

Categories

Resources