简体   繁体   中英

Authentication for separate services in rest API

I am learning Rest api using JAVA and I have completed most of it except authentication. I have created two java web services buyerservice and sellerservice . Inside that there are many sub services with specific paths.

I want to create separate authentication for above services, so that sellers can access sellerservice and buyer can access buyerservices. As of now i have created a filter class and two authentication service class BuyerAuthService and SellerAuthService for each of the above services. In login servlet after authentication I add the encoded base64 value of username and password to cookies under "Authorization" tag. So each time in filter class it gets the cookies and validate them.

This is the filter class:

package com.shopping.client;

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

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

public class RestAuthenticationFilter implements javax.servlet.Filter {
    public static final String AUTHENTICATION_HEADER = "Authorization";

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain filter) throws IOException, ServletException {
        if (request instanceof HttpServletRequest) {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            Cookie[] cookies = httpServletRequest.getCookies();
            String authCredentials = "";
            for (int i = 0; i < cookies.length; i++) {
                  String name = cookies[i].getName();
                  String value = cookies[i].getValue();
                  if(name.equals(AUTHENTICATION_HEADER)){
                      authCredentials = value;
                  }
                }

            //System.out.println(authCredentials);
            // better injected
            final String encodedUserPassword = authCredentials.replaceFirst("Basic"
                    + " ", "");
            String usernameAndPassword = null;
            try {
                byte[] decodedBytes = Base64.getDecoder().decode(
                        encodedUserPassword);
                usernameAndPassword = new String(decodedBytes, "UTF-8");
            } catch (IOException e) {
                e.printStackTrace();
            }
            final StringTokenizer tokenizer = new StringTokenizer(
                    usernameAndPassword, ":");
            final String username = tokenizer.nextToken();
            final String password = tokenizer.nextToken();
            boolean authenticationStatus = false;

            if(username.equals("buyerservice")){

                BuyerAuthService buyAuth = new BuyerAuthService();
                authenticationStatus = buyAuth.authenticate(username, password);
            }
            else if(username.equals("sellerservice"))
            {
                SellerAuthService sellAuth = new SellerAuthService();
                authenticationStatus = sellAuth.authenticate(username, password);
            }

            if (authenticationStatus) {
                filter.doFilter(request, response);
            } else {
                if (response instanceof HttpServletResponse) {
                    HttpServletResponse httpServletResponse = (HttpServletResponse) response;
                    httpServletResponse
                            .setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                }
            }
        }
    }

    @Override
    public void destroy() {
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
    }
}

This is my Buyer Authentication service class method:

public class BuyerAuthService {

    public boolean authenticate(String username, String password) {

        if (null == username)
            return false;
        boolean authenticationStatus = "buyerservice".equals(username)
                && "buyerservice".equals(password);
        return authenticationStatus;
    }
}

The seller authentication service is same as above but with changes like username and password.

My loginservlet is:

String authStringEnc = Base64.getEncoder().encodeToString(authString.getBytes("utf-8"));
System.out.println("Base64 encoded auth string: " + authStringEnc);
if(username.equals("sellerservice")){
    SellerAuthService sellAuth = new SellerAuthService();
    if(sellAuth.authenticate(username, password)){
        Cookie cookie = new Cookie("Authorization", authStringEnc);
        response.addCookie(cookie);
        System.out.println("HeaderSet");
        response.sendRedirect(URL);
    }
    else{

        response.sendError(404, "Wrong username password combination");
    }
}
else if(username.equals("buyerservice")){
    BuyerAuthService buyAuth = new BuyerAuthService();
    if(buyAuth.authenticate(username, password)){
        Cookie cookie = new Cookie("Authorization", authStringEnc);
        response.addCookie(cookie);
        System.out.println("HeaderSet");
        response.sendRedirect(URL);
    }
    else{
        response.sendError(404, "Wrong username password combination");
    }
}
else{
    response.sendError(404, "Username doesn't exists");
}

I get my username and password from the login form.

The problem with the above filter class is even if I am logged into sellerservice , and try to access buyerservice uris, I am able to access it. But I want them to be redirected to unauthorized html page. Please give suggestions and help as I am stuck here. Since I am new to authentication any proper guidance is also helpful to me. Thanks in advance.!

I added separate filters for each services and added the same filter information in web.xml file.

My web.xml file is

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>ElectronicsShopping</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>LoginServlet.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>Electronic Shopping</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>com.shopping.client,com.jersey.jaxb,com.fasterxml.jackson.jaxrs.json</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Electronic Shopping</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
  <filter>
    <filter-name>SellerAuthenticationFilter</filter-name>
    <filter-class>com.shopping.client.SellerAuthenticationFilter</filter-class>
  </filter>
  <filter>
    <filter-name>BuyerAuthenticationFilter</filter-name>
    <filter-class>com.shopping.client.BuyerAuthenticationFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>SellerAuthenticationFilter</filter-name>
    <url-pattern>/rest/sellerservice/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>BuyerAuthenticationFilter</filter-name>
    <url-pattern>/rest/buyerservice/*</url-pattern>
  </filter-mapping>
</web-app>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM