简体   繁体   English

是否有与服务器无关的方式来实现BASIC身份验证?

[英]Is there a server agnostic way to implement BASIC Authentication?

I am attempting to add BASIC authentication to my RESTful web-service. 我正在尝试向我的RESTful Web服务添加BASIC身份验证。 Currently I have BASIC authentication for an Apache Tomcat 6.0 server, but I need to deploy my web-service on a WebSphere application server ver. 目前我对Apache Tomcat 6.0服务器进行BASIC身份验证,但我需要在WebSphere应用程序服务器上部署我的Web服务。 6.1 as well and I am having problems getting BASIC authentication running on WebSphere. 6.1以及我在WebSphere上运行BASIC身份验证时遇到问题。

Is there a way in Java to check the authentication headers of an HTTP request and if the username/password provided (in Base64 encoding) doesn't match a known account force the user to enter in a new username/password? 在Java中是否有办法检查HTTP请求的身份验证标头,如果提供的用户名/密码(以Base64编码)与已知帐户不匹配,则用户输入新的用户名/密码?

I have tried implementing Spring Security, but since my project was made entirely without Spring it has been a huge pain trying to get it to work, and I am attempting to find a simple solution to my rather simple problem. 我已经尝试过实现Spring Security,但由于我的项目完全没有Spring,所以试图让它工作是一件巨大的痛苦,我试图找到一个简单的解决方案来解决我的相当简单的问题。

Technologies that I am currently using include: Java, Jersey/JAX-RS, Eclipse with Maven plugin. 我目前使用的技术包括:Java,Jersey / JAX-RS,带Maven插件的Eclipse。

You should be able to setup a servlet filter which gets executed before your REST handlers, inspects the "Authorization" request header, base 64 decodes it, extracts the username and password, and verifies. 您应该能够设置一个servlet过滤器 ,该过滤器在您的REST处理程序之前执行,检查“授权”请求标头, 基本64解码它,提取用户名和密码,并进行验证。 Something like this: 像这样的东西:

public void doFilter(ServletRequest req,
                     ServletResponse res,
                     FilterChain chain) {
  if (request instanceof HttpServletRequest) {
    HttpServletRequest request = (HttpServletRequest) req;
    String authHeader = Base64.decode(request.getHeader("Authorization"));
    String creds[] = authHeader.split(":");
    String username = creds[0], password = creds[1];
    // Verify the credentials here...
    if (authorized) {
      chain.doFilter(req, res, chain);
    } else {
      // Respond 401 Authorization Required.
    }
  }
  doFilter(req, res, chain);
}

All servlet containers have a standard way to configure filter chains. 所有servlet容器都有一种配置过滤器链的标准方法。

Complete implementation based on maerics answer. 基于maerics答案的完整实现。

import java.io.IOException;

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 org.apache.commons.lang.StringUtils;

import sun.misc.BASE64Decoder;

public class AuthenticationFilter implements Filter {

    private static final String AUTHORIZATION_HEADER_NAME = "Authorization";
    private static final String WWW_AUTHENTICATE_HEADER_NAME = "WWW-Authenticate";
    private static final String WWW_AUTHENTICATE_HEADER_VALUE = "Basic realm=\"Default realm\"";
    private static final String BASIC_AUTHENTICATION_REGEX = "Basic\\s";
    private static final String EMPTY_STRING = "";
    private static final String USERNAME_PASSWORD_SEPARATOR = ":";
    private static final BASE64Decoder DECODER = new BASE64Decoder();

    public void init(FilterConfig arg0) throws ServletException {
    }

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest httpReq = (HttpServletRequest) req;
        HttpServletResponse httpRes = (HttpServletResponse) res;

        String authHeader = httpReq.getHeader(AUTHORIZATION_HEADER_NAME);

        if (authHeader == null) {
            this.requestAuthentication(httpRes);
            return;
        }

        authHeader = authHeader.replaceFirst(BASIC_AUTHENTICATION_REGEX, EMPTY_STRING);
        authHeader = new String(DECODER.decodeBuffer(authHeader));      

        if (StringUtils.countMatches(authHeader, USERNAME_PASSWORD_SEPARATOR) != 1) {
            this.requestAuthentication(httpRes);
            return;         
        }

        String[] creds = authHeader.split(USERNAME_PASSWORD_SEPARATOR);
        String username = creds[0];
        String password = creds[1];         

        //TODO: implement this method
        if (!authenticatedUser(username, password)) {
            this.requestAuthentication(httpRes);
            return;
        }

         chain.doFilter(req, res);
    }

    private void requestAuthentication(HttpServletResponse httpRes) {

        httpRes.setHeader(WWW_AUTHENTICATE_HEADER_NAME, WWW_AUTHENTICATE_HEADER_VALUE);
        httpRes.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    }

    public void destroy() {
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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