安卓设备在Lotus Domino服务器上进行HTTP身份验证

3

我正在开发一款安卓应用程序,能够从Lotus Domino数据库中读取数据。我开始创建一个页面来测试HTTP身份验证,但是遇到了许多困难。这是我的代码片段:

    public void GoAuth(View v){
    final String httpsURL = "http://xxx.xxx.xxx.xxx/names.nsf/mypage?openpage";
    final DefaultHttpClient client = new DefaultHttpClient();
    final HttpPost httppost = new HttpPost(httpsURL);

    String userName = "demo";
    String password = "demo";

    try {
        //authentication block:
        final List<BasicNameValuePair> nvps = new ArrayList<BasicNameValuePair>();
        nvps.add(new BasicNameValuePair("Username", userName));
        nvps.add(new BasicNameValuePair("Password", password));
        final UrlEncodedFormEntity p_entity = new UrlEncodedFormEntity(nvps, HTTP.UTF_8);
        httppost.setEntity(p_entity);

        //sending the request and retrieving the response:
        HttpResponse response = client.execute(httppost);
        HttpEntity responseEntity = response.getEntity();

        if (response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK){
            //handling the response 
            final InputSource inputSource = new InputSource(responseEntity.getContent());
            TextView res=(TextView)findViewById(R.id.result);
            res.setText("Server response: "+inputSource.toString());
        }

    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalStateException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

服务器的响应是: org.xml.sax InputSource@40575700
在浏览器中尝试同样的操作,我能够看到登录页面和“我的页面”的内容。 对于在Android上正确的方法和机制,我有些困惑。 非常感谢您的帮助!

你希望得到的响应是什么?HTML?创建一个InputSource除了准备从服务器接收的内容以便被解析器(例如SAX解析器)解析之外,没有任何作用。你只是想要转储服务器的响应吗?如果是这样,那么你应该使用EntityUtils#toString(responseEntity)。 - Jens
你是看到登录页面还是登录对话框?如果你看到的是完整的页面,那么Domino服务器配置为使用会话(基于cookie)身份验证而不是基本身份验证。 - Richard Schwartz
@rhsatrhs 我看到了登录页面,服务器配置为使用会话认证。 - Vincent
@Jens 我期望得到HTML作为响应; 我尝试了你的建议,替换了这一行代码 res.setText("Server response: "+EntityUtils.toString(response.getEntity())); 但是收到了一个IllegalStateException异常,"Content has been consumed"。 - Vincent
如果您已经尝试读取实体中的内容,则会抛出异常。只调用一次response.getEntity(),并且只尝试读取它返回的InputStream一次。 - Jens
好的,谢谢。现在我可以看到服务器响应,即登录页面的HTML...所以我的身份验证函数失败了。 - Vincent
3个回答

2

1
如上述代码将适用于向Domino服务器发布凭据,但您需要处理任何登录失败的问题 - 无论是由于身份验证还是授权引起的。
顺便说一句,绕过Domino登录表单通常在客户端完成,如此处所示 - http://www.codestore.net/store.nsf/unid/BLOG-20081008,并且存在相同的问题。
在我的博客中,我谈到了在Domino配置数据库中创建自定义登录表单的方法 - 这是一个标准和内置的配置数据库。该自定义登录表单不是为直接打开而设计的,而是为第三方系统进行身份验证,然后返回带有任何身份验证/授权问题的JSON数据。
如果您发现在Java代码中使用XML更容易消耗,则可以使用相同的方法进行转换。
文章链接在这里:http://www.markbarton.com/?p=314 这里有关于Domino配置数据库(domconfig.nsf)的信息链接 http://publib.boulder.ibm.com/infocenter/domhelp/v8r0/index.jsp?topic=%2Fcom.ibm.help.domino.admin.doc%2FDOC%2FH_CREATING_THE_DOMINO_CONFIGURATION_DATABASE.html

1
这是我在几个与Lotus Domino同步的Android应用程序中使用的一些代码的核心部分:
    private boolean authenticateWithDomino() throws Exception {

    String fullLoginUrl = "";

    if (useSSL) {
        fullLoginUrl = "https://" + hostName + ":" + httpPort + "/names.nsf?Login";
    } else {
        fullLoginUrl = "http://" + hostName + ":" + httpPort + "/names.nsf?Login";
    }

    DominoHttpRequest dominoRequest = DominoHttpClient.getInstance()
            .createRequest();
    dominoRequest.setUrl(fullLoginUrl);
    dominoRequest.setMethod("POST");
    dominoRequest.addParam("username", notesName);
    dominoRequest.addParam("password", notesPassword);
    dominoRequest.addParam("redirectto", "/icons/ecblank.gif");
    dominoRequest.execute();
    }

使用说明:

  • 此项适用于基于Session的身份验证,但不适用于基本身份验证。
  • names.nsf可能不是服务器目录的文件名,但通常是这样的。
  • 请注意端口号。通常,常规http的端口号为80,https的端口号为443,但在Domino服务器上可以进行配置。

稍后添加... 这里有一个执行与Domino“复制”相应操作的Java类的链接:DiscussionReplicator.java。查找一个名为getAuthenticationToken的方法,该方法返回“DominoAuthSessID=xyz”或“LtpaToken=abc”中的一个。


非常感谢,Jens。我不太理解DominoHttpRequest和DominoHttpClient这两个类。能否提供更多细节?(它们是自定义类吗?我应该使用标准的org.apache.http.HttpRequest吗?) - Vincent
是的,DominoHttpRequest和DominoHttpClient是我自定义的类。我无法在互联网上公开所有代码。我正在使用org.apache.http.impl.client.DefaultHttpClient。 - Jbruntt
太好了!感谢您的建议,我成功了!我使用了HTTP基本身份验证,并考虑了安全性;使用https足以对抗流量嗅探器吗? - Vincent
HTTPS可以保护密码免受流量嗅探器的攻击。但是,一个有决心和适当资源的黑客可能仍然能够获取密码和用户名。这里有一个好的资源:https://dev59.com/73VC5IYBdhLWcg3ww0Hr - Jbruntt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接