【问题标题】:Is there a server agnostic way to implement BASIC Authentication?是否有一种与服务器无关的方式来实现基本身份验证?
【发布时间】:2011-09-15 16:34:53
【问题描述】:

我正在尝试将 BASIC 身份验证添加到我的 RESTful Web 服务。目前我有一个 Apache Tomcat 6.0 服务器的 BASIC 身份验证,但我需要在 WebSphere 应用程序服务器版本上部署我的 Web 服务。 6.1 以及我在 WebSphere 上运行 BASIC 身份验证时遇到问题。

Java 中是否有办法检查 HTTP 请求的身份验证标头,如果提供的用户名/密码(以 Base64 编码)与已知帐户不匹配,是否会强制用户输入新的用户名/密码?

我曾尝试实施 Spring Security,但由于我的项目完全没有 Spring,因此尝试使其工作非常痛苦,我正在尝试为我相当简单的问题找到一个简单的解决方案。

我目前使用的技术包括:Java、Jersey/JAX-RS、带有 Maven 插件的 Eclipse。

【问题讨论】:

标签: java jersey websphere-6.1 basic-authentication tomcat


【解决方案1】:

您应该能够设置一个servlet filter,它会在您的 REST 处理程序之前执行,检查“授权”请求标头 base 64 decodes 它,提取用户名和密码并进行验证。像这样的:

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

所有 servlet 容器都有配置过滤器链的标准方法。

【讨论】:

    【解决方案2】:

    基于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() {
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-31
      • 2016-10-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多