2012-12-05 30 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”访问它吗? –

相关问题