2011-06-15 16 views
6

RESTful WebサービスにBASIC認証を追加しようとしています。現在、私はApache Tomcat 6.0サーバーの基本認証を持っていますが、WebアプリケーションサーバーをWebSphereアプリケーションサーバーに展開する必要があります。 6.1でも問題があり、WebSphereでBASIC認証を実行するのに問題があります。BASIC認証を実装するためのサーバーにとらわれない方法はありますか?

HTTP要求の認証ヘッダーを確認する方法がありますか?(Base64エンコーディングで提供された)ユーザー名とパスワードが既知のアカウントと一致しない場合、ユーザーは新しいユーザー名/パスワードを入力する必要がありますか?

私はSpring Securityを実装しようとしましたが、私のプロジェクトがSpringなしで完全に作成されて以来、動作させるのに苦労していました。簡単な解決策を見つけることを試みています。

私が現在使用している技術には、Java、Jersey/JAX-RS、Mavenプラグイン付きEclipseが含まれます。

+0

http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/twbs_auwschta.html ? –

+0

@Marc私はそのpdfを見てきました。それはサンプルサーバーにとって非常に特有です。私はWebSphereが既にインストールされている(私はそれを制御できません)まったく別のサーバーを使用しています。これらの構成は、展開しようとしているサーバーと一致しません。 –

答えて

9

RESTハンドラの前に実行され、 "Authorization"リクエストヘッダー、base 64 decodesを検査し、ユーザー名とパスワードを抽出して確認するservlet filterをセットアップする必要があります。このようなもの:

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

すべてのサーブレットコンテナには、標準的なフィルタチェーンの設定方法があります。

+0

これは完璧に機能しました!ありがとうございました。 –

4

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() { 
    } 
} 
関連する問題