【问题标题】:Authentication for separate services in rest APIREST API 中单独服务的身份验证
【发布时间】:2018-05-09 03:47:28
【问题描述】:

我正在使用 JAVA 学习 Rest api,除了身份验证之外,我已经完成了大部分。我创建了两个 java web 服务buyerservicesellerservice。里面有许多具有特定路径的子服务。

我想为上述服务创建单独的身份验证,以便卖家可以访问卖家服务,买家可以访问买家服务。到目前为止,我已经为上述每个服务创建了一个过滤器类和两个身份验证服务类BuyerAuthServiceSellerAuthService。在身份验证后的登录 servlet 中,我将用户名和密码的编码 base64 值添加到“授权”标签下的 cookie 中。因此,每次在过滤器类中,它都会获取 cookie 并对其进行验证。

这是过滤器类:

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 {
    }
}

这是我的买家身份验证服务类方法:

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;
    }
}

卖家身份验证服务同上,只是用户名和密码等变化。

我的 loginservlet 是:

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");
}

我从登录表单中获取了我的用户名和密码。

上述过滤器类的问题是即使我登录到sellerservice,并尝试访问buyerservice uris,我也能够访问它。 但我希望他们被重定向到未经授权的 html 页面。当我被困在这里时,请提供建议和帮助。由于我不熟悉身份验证,因此任何适当的指导对我也有帮助。提前致谢!

【问题讨论】:

    标签: java rest authentication cookies


    【解决方案1】:

    我为每个服务添加了单独的过滤器,并在 web.xml 文件中添加了相同的过滤器信息。

    我的 web.xml 文件是

    <?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>
    

    【讨论】:

      猜你喜欢
      • 2014-01-10
      • 2013-11-12
      • 1970-01-01
      • 2020-06-24
      • 2014-12-25
      • 2013-06-22
      • 2019-04-07
      • 2018-07-26
      • 2019-10-02
      相关资源
      最近更新 更多