First of all, you must think about why use JWT.
JWT were created to attend particular problems of modern web applications, principally the server state problem that represent cookies.
1. Apps are distributed across many servers
Many of today's applications aren't deployed the same way they were in
the past. It is now very common--and often necessary--for apps to be
distributed across many servers so that up-time is increased and
latency issues are mitigated. With this comes the side effect that,
when a user accesses an application, it is no longer guaranteed that
they are always accessing the same server.
Since traditional authentication relies on the server to keep the
user's authentication state in memory, things break down when the app
is accessed from different servers. The user might be logged in on one
server but not on the others that the application is distributed
across.
2. Apps use APIs for data
Using APIs in this fashion is great, but things can become challenging
when it comes to authentication. The traditional approach of using
sessions and cookies for the user's identity doesn't work so well in
these cases because their use introduces state to the application. One
of the tenets of a RESTful API is that it should be stateless, meaning
that, when a request is made, a response within certain parameters can
always be anticipated without side effects. A user's authentication
state introduces such a side effect, which breaks this principle.
Keeping the API stateless and therefore without side effect means that
maintainability and debugging are made much easier.
3. CORS (very common with Single Page Applications)
Another challenge here is that it is quite common for an API to be served > from one server and for the actual application to consume it from another.
To make this happen, we need to enable Cross-Origin Resource Sharing
(CORS). Since cookies can only be used for the domain from which they
originated, they aren't much help for APIs on different domains than
the application.
RESTful APIs are more common with each day and they must be stateless by definition.
The stateless feature allows horizontal scaling because a request can be attended by any server.
You can have a simpler JSON API with a stateless backend and benefit from the horizontal scalling without REST.
So, you can use Custom JWT authentication that integrates with Spring and benefit from the authorization part if you require complex authorization like method authorization.
When you say
Shall jwt token be stored in session rather than cookie?
I think you don't fully get the idea of JWT because the JWT token does not have to be stored in the server-side (session). This would mean state in server side what is JWT comes to avoid.
The JWT must be created on succesfull user authentication against a login endpoint (something like /login). This work will be done by a AuthenticationSuccessHandler that is injected to the UsernamePasswordAuthenticationFilter. For example:
public class JWTAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
protected JWSSigner jwsSigner;
public JWTAuthenticationSuccessHandler(JWSSigner jwsSigner){
this.jwsSigner = jwsSigner;
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
String ipaddress = request.getRemoteAddr();
JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder();
JWTClaimsSet claimsSet = builder.subject("subject").issuer("issuer").expirationTime(new Date(new Date().getTime() + 60 * 1000)).claim("ipaddress",ipaddress).build();
SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.HS256), claimsSet);
try {
signedJWT.sign(jwsSigner);
String serializedJWT = signedJWT.serialize();
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getOutputStream().println(serializedJWT);
} catch (JOSEException e) {
e.printStackTrace();// TODO
}
}
}
Then, the client must store the token in localStorage or cookie and send it with each request. The server will only verify the integrity of the token, authentication against user credentials is no longer needed (unless the token has expired).
So, what you expect from JWT? What features must accomplish your authentication mechanism?