DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Composing Custom Annotations in Spring
  • Spring OAuth Server: Token Claim Customization
  • Exploring API Headers
  • Modern Web Applications Authentication Using Face Recognition

Trending

  • Agile’s Quarter-Century Crisis
  • Traditional Testing and RAGAS: A Hybrid Strategy for Evaluating AI Chatbots
  • Navigating and Modernizing Legacy Codebases: A Developer's Guide to AI-Assisted Code Understanding
  • The Perfection Trap: Rethinking Parkinson's Law for Modern Engineering Teams
  1. DZone
  2. Coding
  3. Frameworks
  4. How to Make a Stateless (Session-less) Authentication With Spring

How to Make a Stateless (Session-less) Authentication With Spring

In this article, I want to focus on how to deal with automatic re-authentication of each HTTP and HTTPS requests. Read on for more info.

By 
OBEN ISIK user avatar
OBEN ISIK
·
Mar. 01, 16 · Tutorial
Likes (18)
Comment
Save
Tweet
Share
106.6K Views

Join the DZone community and get the full member experience.

Join For Free

If we think about the meaning of authentication, it seems that it is all about a client identifying itself to the server. After client identification is done, the server can remember the client each time the request comes from the client. There are two common approaches to authentication mechanisms: one of them is called "Session Cookie Based" and the other one is "Token Based".

In this article, I want to focus on how to deal with automatic re-authentication of each HTTP and HTTPS requests.

What Does "Session Cookie Based Authentication" Mean?

In today's world, especially for corporate businesses, the most common usage of authentication is the session-based approach. In the session-based approcah, a session id—which is a kind of server generated token—is generated and stored in a cookie within the JSESSIONID paramter. This means that the server stores the session key in itself so when the server reboots or requests are redirected to another server by load balancers, your "state" of session key becomes useless.

What Does "Stateless Authentication" Mean?

Whenever you are talking about REST API's , API keys are mentioned too. Basically, they involve sending custom tokens or custom keys within the HTTP Request header. There are several approaches such as OAUTH1, OAUTH2, Basic Authentication, etc. for implementing stateless authentication and today we will be focus on "Server Signed Token" approach that may be life-saving for your implementations.

Server Signed Token Approach

First of all, it is easy to imagine that, in this approach; if server gets a request from the client, the client should send a token and the server should check and sign it before giving any response to the client.

With "Server Signed Tokens" a user identification data is shared with the server for authentication and when the server authenticates the user, it gives a hash key which is called a "token" to the client. After this step, the client can use this token to ask for any request to the server so the server should sign and approve that the token is valid for request.

Let's get into the details of the implementation of this approach.

The first step is authentication. In the authentication step, the client sends its user-specific identification data to the server and if this data is correct, the server response is a token to the client with HTTP 200 OK. If the data is incorrect, the server response is an HTTP 403 Forbidden.

Ekran Resmi 2016-02-25 20.43.47

After this approval is done, the client can send another requests without giving any user-specific identification data to the server again again. The client only uses this token for further requests.

Ekran Resmi 2016-02-25 20.49.35The Recipe for Implementing Token Approach With Spring

To understand all of the steps easily, it is good to have a scenario. For example, we want to make a login page with the inputs of username and password. And, after the user is logged in successfully, we want to show the user profile page with user information in it.

In Spring, we have WebSecurityConfigurerAdapters which help to implement the security configurations of our spring project easily. In these adapters, there is a "configure" method for HTTP securities.

In this configure method, we should add two filters which will be used in login step and the authentication step.

@Override
protected void configure(HttpSecurity http) throws Exception {
  http.csrf().disable();
  http.exceptionHandling()
    .and()
    .anonymous()
    .and()
    .servletApi()
    .and()
    .headers().cacheControl()
    .and()
    .authorizeRequests().antMatchers(HttpMethod.OPTIONS,"/api/auth/login").permitAll()
    .anyRequest().authenticated()
    .and()
    .addFilterBefore(new LoginFilter(new AntPathRequestMatcher("/api/auth/login")), UsernamePasswordAuthenticationFilter.class)
    .addFilterBefore(new AuthFilter(), UsernamePasswordAuthenticationFilter.class);
}

Full Verion Of The Java Class Can Be Found Here

As you see in the last two lines, we have a "Login Filter" which will be called with any request path equals to "/api/auth/login". Also, for any other requests the "Auth Filter" will be called before each request is processed.

Ekran Resmi 2016-02-25 21.15.44









Spring provides an "AbstractAuthenticationProcessingFilter" which is used for authentication.

Because of this helpfull abstract class, we extend our Login Filter from the AbstractAuthenticationProcessingFilter. This filter has "attemptAuthentication", "successfulAuthentication" and "unsuccessfulAuthentication" methods to override.

In attemptAuthentication method, the aim is to create an Authentication object (org.springframework.security.core.Authentication) that stores the authorities, credentials, details, principal object, and authenticationResult.

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
  throws AuthenticationException, IOException, ServletException { 
  UserAuthentication auth = (UserAuthentication) tokenAuthenticationService.getAuthenticationForLogin(request,
                                                                                                      response);
  if (!auth.isAuthenticated()) {
    throw new UserAuthenticationException("Auth to FTAPI is Failed.", auth);
  }

  return auth;
}

If the attemptAuthentication method throws a UserAuthenticationException the unsuccessfullAuthentication method is called, otherwise the successfullAuthentication method will be called.

So, the aim of this method is to just check whether the username and password is correct or not, and then set the isAuthenticated parameter to true and false. If the parameter is false, it throws an exception to process the success and fail operations.

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                        javax.servlet.FilterChain chain, Authentication authResult) throws IOException, ServletException {

  try {
    UserAuthentication authResultObject = (UserAuthentication) authResult;
    tokenAuthenticationService.addAuthentication(response, authResultObject);

    // Add the authentication to the Security context
    SecurityContextHolder.getContext().setAuthentication(authResult);
  } catch (Exception ex) {
    ex.printStackTrace();
  }
}

As it is easy to understand from the implementation, the token is created in the addAuthentication method and stored in the security context.

A common question is: where do you store the tokens for both client and server. It depends on your requirements. For example, you can create the token and store it in a cache server with a token, user hashmap and when the user sends a request with that token, you can get the token details from this cache server or you can store the token you generated in a database, etc.

When the server creates the token, this token should be told to the client in the HTTP response. The common best practice of that is to respond to this token in the header of the HTTP reponse with a parameter name which is called "X-AUTH-TOKEN". This step is very important because the client will always come with this X-AUTH-TOKEN parameter which contains a token for each HTTP request.

After the token handshake is done, when the client makes a request to the server, Auth Filter will be called. The working style of the auth filter is very easy because the only job it needs to do is get the X-AUTH-TOKEN value from the request header and get the user object from the cache server. If the user object already exits, that means there is a user that has a valid and not dead token. If the user object does not, all the filter needs to do is changing the response HTTP status code to 403 which means unforbidden.

authentication Spring Framework Requests

Opinions expressed by DZone contributors are their own.

Related

  • Composing Custom Annotations in Spring
  • Spring OAuth Server: Token Claim Customization
  • Exploring API Headers
  • Modern Web Applications Authentication Using Face Recognition

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!