2012-12-05 81 views
2

我正在編寫一個用於發送和接收消息的基本Android應用程序。我還使用Tomcat 7.0.21編寫服務器端代碼。我目前正在嘗試實施「程序化Web應用程序安全性」(http://courses.coreservlets.com/Course-Materials/msajsp.html),其中明確執行客戶機認證。Tomcat在處理具有驗證標頭的android請求之前發送400s

我現在已經完成了這個實現,當我使用REST客戶端發送請求時,它工作正常。但是,當我從Android設備/模擬器發送請求時,我得到一個java.io.FileNotFoundException。當我檢查tomcat訪問日誌時,似乎tomcat在我的Servlet代碼甚至執行之前發送了400錯誤請求,從而產生異常。

我不知道這個問題是客戶端還是服務器端。任何有關如何實施這一點的見解或建議都會被大大地解釋。謝謝。

Tomcat的localhost_access_log:

192.168.1.2 - - [05/Dec/2012:12:20:39 +0100] "GET /CA/users/get_contacts?user_id=freespirit HTTP/1.1" 400 - 

servlet類我延長,這一點我相信是永遠不會被執行:

package carter.server.conversations; 

import java.io.IOException; 
import java.sql.Connection; 
import java.sql.SQLException; 

import javax.servlet.ServletException; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import sun.misc.BASE64Decoder; 
import carter.sqlite.SQLiteUtilities; 
import carter.sqlite.conversations.DatabaseHelper; 

public class AuthorizationServlet extends HttpsServlet { 

    protected static final int SERVLET_EXCEPTION_UNAUTHORIZED = 1; 

    @Override 
    protected void doGet(HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException { 

     super.doGet(request, response); 

     String authorization = request.getHeader("Authorization"); 
     if(authorization == null){ 
      System.out.println("CAAuthorizationServlet: Authorization is null. Sending 401."); 
      response.sendError(HttpServletResponse.SC_UNAUTHORIZED); 
     } 
     else{ 
      String base64encodedDetails = authorization.substring(6).trim(); //remove "BASIC " prefix 
      BASE64Decoder decoder = new BASE64Decoder(); 
      String unencodedDetails = new String(decoder.decodeBuffer(base64encodedDetails)); 
      String[] userDetails = unencodedDetails.split(":"); 
      //check database for given details 
      Connection databaseConnection = SQLiteUtilities.getConnection(Constants.databasePath); 
      try{ 
       String password = DatabaseHelper.getPassword(userDetails[0], databaseConnection); 
       if(password.equals(userDetails[1]) == false){ 
        //password does not match this user 
        System.out.println("CAAuthorizationServlet: password does not match this user. Sending 401."); 
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED); 
       } 
      } 
      catch(SQLException e){ 
       // no such user found in database. 
       System.out.println("CAAuthorizationServlet: no such user exists in database. Sending 401."); 
       response.sendError(HttpServletResponse.SC_UNAUTHORIZED); 
      } 
      finally{ 
       SQLiteUtilities.closeConnection(databaseConnection); 
      } 
     } 
    } 

    @Override 
    protected void doPost(HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException { 

     super.doPost(request, response); 
     doGet(request, response); 
    } 

} 


package carter.server.conversations; 

import java.io.IOException; 

import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

public class HttpsServlet extends HttpServlet { 

    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 

     System.out.println("CAHttpsServlet: checking request is secure"); 
     if(request.isSecure() == false){ 
      System.out.println("CAHttpsServlet: Request is NOT secure. Sending 400"); 
      response.sendError(HttpServletResponse.SC_BAD_REQUEST); 
     } 
    } 

    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 

     doGet(request, response); 
    } 

} 

回答

1

嗯,你是拒絕在自己的代碼請求:

protected void doGet(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException { 

    System.out.println("CAHttpsServlet: checking request is secure"); 
    if(request.isSecure() == false){ 
     System.out.println("CAHttpsServlet: Request is NOT secure. Sending 400"); 
     response.sendError(HttpServletResponse.SC_BAD_REQUEST); 
    } 
} 
+0

我註釋掉了'sendError'行,但仍然沒有運氣。我從來沒有看到前面的日誌消息。 –

+0

你在檢查你的catalina.out日誌文件嗎? – Perception

+0

我正在使用eclipse,所以Catalina.out日誌記錄可以在控制檯中看到(我不是100%確定的,所以請糾正我,如果我錯了)。此示例在重新加載後直接進行:'06-Dec-2012 16:45:49 org.apache.catalina.core.StandardContext重新加載 信息:用名稱[/ CA]重新裝入上下文 carter.server.conversations.SignIn |安全請求:真 用戶freespirit用密碼sweetypie試圖登錄 java.lang.UnsatisfiedLinkError:本地庫/tmp/sqlite-3.7.2-libsqlitejdbc.so已經加載到另一個類加載器中 成功登錄' –

0

看來它與Same Origin Policy有關。

您需要在Tomcat服務器上啓用跨域請求。

對於這一點,你需要創建你的Tomcat的ROOT Web應用程序一個crossdomain.xml文件,用這樣的內容:

<?xml version="1.0"?> 
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> 
<cross-domain-policy> 
    <site-control permitted-cross-domain-policies="all"/> 
    <allow-access-from domain="*" /> 
    <allow-http-request-headers-from domain="*" headers="*"/> 
</cross-domain-policy> 
+0

我將文件完全拷貝到ROOT webapp中,但不幸的是,這並沒有奏效。我不確定這是否是問題。我的所有代碼都位於同一個webapp中,所有請求都在端口8443上進行。 –

+0

設置完此文件後,您可以通過「https:// host:8443/crossdomain.xml」訪問它嗎? –

相關問題