Tuesday, 8 January 2019

Basic Authentication using servlets example


In this post, I am going to explain basic authentication using servlets.

I am going to develop below API that is secured by basic authentication.

HTTP Method
Server URL
Description
GET

Get all the users information
POST

Create new user.

Below snippet reads the user credentials from ‘Authorization’ header.
private static Credentials getCredentials(HttpServletRequest req) {
  String authHeader = req.getHeader("Authorization");

  if (authHeader == null)
   return null;

  StringTokenizer st = new StringTokenizer(authHeader);
  if (st.hasMoreTokens()) {
   String basic = st.nextToken();

   if (basic.equalsIgnoreCase("Basic")) {
    try {
     String credentials = new String(Base64.getDecoder().decode(st.nextToken()), "UTF-8");
     int p = credentials.indexOf(":");
     if (p != -1) {
      String login = credentials.substring(0, p).trim();
      String password = credentials.substring(p + 1).trim();

      return new Credentials(login, password);
     }
    } catch (UnsupportedEncodingException e) {
     return null;
    }
   }
  }


Below snippet checks user credentials and create session for valid user, else send 403 response.

 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
   throws IOException, ServletException {
  HttpServletRequest req = (HttpServletRequest) request;
  HttpSession session = req.getSession(false);

  if (session == null) {
   Credentials credentials = getCredentials(req);
   if (credentials == null) {
    ((HttpServletResponse) response).sendError(403);
    return;
   }
   if ("admin".equals(credentials.getUserName()) && "password".equals(credentials.getPassword())) {
    session = req.getSession();
    session.setAttribute("sessionCreated", true);
   } else {
    ((HttpServletResponse) response).sendError(403);
    return;
   }

  }
  chain.doFilter(request, response);
 }

Find the below working application.


AuthFilter.java
package com.sample.filters;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Base64;
import java.util.StringTokenizer;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.sample.model.Credentials;

public class AuthFilter implements Filter {

 public AuthFilter() {
 }

 public void destroy() {

 }

 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
   throws IOException, ServletException {
  HttpServletRequest req = (HttpServletRequest) request;
  HttpSession session = req.getSession(false);

  if (session == null) {
   Credentials credentials = getCredentials(req);
   if (credentials == null) {
    ((HttpServletResponse) response).sendError(403);
    return;
   }
   if ("admin".equals(credentials.getUserName()) && "password".equals(credentials.getPassword())) {
    session = req.getSession();
    session.setAttribute("sessionCreated", true);
   } else {
    ((HttpServletResponse) response).sendError(403);
    return;
   }

  }
  chain.doFilter(request, response);
 }

 private static Credentials getCredentials(HttpServletRequest req) {
  String authHeader = req.getHeader("Authorization");

  if (authHeader == null)
   return null;

  StringTokenizer st = new StringTokenizer(authHeader);
  if (st.hasMoreTokens()) {
   String basic = st.nextToken();

   if (basic.equalsIgnoreCase("Basic")) {
    try {
     String credentials = new String(Base64.getDecoder().decode(st.nextToken()), "UTF-8");
     int p = credentials.indexOf(":");
     if (p != -1) {
      String login = credentials.substring(0, p).trim();
      String password = credentials.substring(p + 1).trim();

      return new Credentials(login, password);
     }
    } catch (UnsupportedEncodingException e) {
     return null;
    }
   }
  }

  return null;

 }

 @Override
 public void init(FilterConfig filterConfig) throws ServletException {
  // TODO Auto-generated method stub

 }

}


Credentials.java
package com.sample.model;

public class Credentials {
 private String userName;
 private String password;

 public Credentials(String userName, String password) {
  super();
  this.userName = userName;
  this.password = password;
 }

 public String getUserName() {
  return userName;
 }

 public void setUserName(String userName) {
  this.userName = userName;
 }

 public String getPassword() {
  return password;
 }

 public void setPassword(String password) {
  this.password = password;
 }

}


DataContainer.java
package com.sample.servlets;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DataContainer extends HttpServlet {
 private static final long serialVersionUID = 1L;

 private static List<String> container = new ArrayList<>();

 public DataContainer() {
  super();

 }

 protected void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {

  response.getWriter().write(container.toString());
 }

 protected void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  String data = getData(request.getInputStream());
  container.add(data);
  response.getWriter().write("Data written successfully");
 }

 private static String getData(InputStream is) throws IOException {
  StringBuilder sb = new StringBuilder();
  BufferedReader br = new BufferedReader(new InputStreamReader(is));
  String read;

  while ((read = br.readLine()) != null) {
   sb.append(read);
  }

  br.close();
  return sb.toString();
 }

}


web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://xmlns.jcp.org/xml/ns/javaee"
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
 id="WebApp_ID" version="3.1">
 <display-name>dataContainer</display-name>
 <welcome-file-list>
  <welcome-file>index.html</welcome-file>
  <welcome-file>index.htm</welcome-file>
  <welcome-file>index.jsp</welcome-file>
  <welcome-file>default.html</welcome-file>
  <welcome-file>default.htm</welcome-file>
  <welcome-file>default.jsp</welcome-file>
 </welcome-file-list>

 <filter>
  <filter-name>authentication</filter-name>
  <filter-class>com.sample.filters.AuthFilter</filter-class>
 </filter>

 <filter-mapping>
  <filter-name>authentication</filter-name>
  <url-pattern>/api/*</url-pattern>
 </filter-mapping>

 <servlet>
  <servlet-name>userDetails</servlet-name>
  <servlet-class>com.sample.servlets.DataContainer</servlet-class>
 </servlet>

 <servlet-mapping>
  <servlet-name>userDetails</servlet-name>
  <url-pattern>/api/userDetails</url-pattern>
 </servlet-mapping>

</web-app>


index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
 <h1>Hello World</h1>
</body>
</html>


Complete project structure looks like below.

Run the application ‘dataContainer’ in application server.

Use any rest client like postman and hit below request.

Method: POST
Body:
{
"name" : "Krishna",
"age" : 29
}


Set the authorization header.


Hit the request.
Hit below request to get the user details.

Method: GET



You can download complete application from below github link.



Previous                                                 Next                                                 Home<

No comments:

Post a Comment