14

基本的に私がする必要があるのはダイジェスト認証を実行することです。私が最初に試したのは、ここで入手できる公式の例です。しかし、それを実行しようとすると(いくつかの小さな変更を加えて、Getメソッドの代わりにPost)、

org.apache.http.auth.MalformedChallengeException: missing nonce in challange
at org.apache.http.impl.auth.DigestScheme.processChallenge(DigestScheme.java:132)

これが失敗したとき、私は使用しようとしました:

DefaultHttpClient client = new DefaultHttpClient();
client.getCredentialsProvider().setCredentials(new AuthScope(null, -1, null), new UsernamePasswordCredentials("<username>", "<password>"));

HttpPost post = new HttpPost(URI.create("http://<someaddress>"));
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("domain", "<username>"));
post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));

DigestScheme digestAuth = new DigestScheme();
digestAuth.overrideParamter("algorithm", "MD5");
digestAuth.overrideParamter("realm", "http://<someaddress>");
digestAuth.overrideParamter("nonce", Long.toString(new Random().nextLong(), 36));
digestAuth.overrideParamter("qop", "auth");
digestAuth.overrideParamter("nc", "0");
digestAuth.overrideParamter("cnonce", DigestScheme.createCnonce());

Header auth = digestAuth.authenticate(new
      UsernamePasswordCredentials("<username>", "<password>"), post);
System.out.println(auth.getName());
System.out.println(auth.getValue());
post.setHeader(auth);


HttpResponse ret = client.execute(post);
ByteArrayOutputStream v2 = new ByteArrayOutputStream();
ret.getEntity().writeTo(v2);
System.out.println("----------------------------------------");
System.out.println(v2.toString());
System.out.println("----------------------------------------");
System.out.println(ret.getStatusLine().getReasonPhrase());
System.out.println(ret.getStatusLine().getStatusCode());

最初は、「レルム」と「ノンス」のDigestSchemeパラメーターのみをオーバーライドしました。しかし、サーバーで実行されているPHPスクリプトには他のすべてのパラメーターが必要であることが判明しましたが、それらを指定するかどうかに関係なく、authenticateSchemeはauthenticate()メソッドを呼び出したときにAuthorizationRequestPrepertyでそれらを生成しません。また、PHPスクリプトはHTTP応答コード200を返し、PHPスクリプトにはcnonce、nc、およびqopパラメーターが必要であるというメッセージが表示されます。

私はこれに2日間苦労してきましたが、運がありません。すべてに基づいて、問題の原因はPHPスクリプトにあると思います。アプリが不正にアクセスしようとしても、チャレンジは送信されないように見えます。

誰かアイデアはありますか?

編集:もう1つ、cURLで接続してみましたが、機能します。

4

4 に答える 4

5

このコードスニペットは私にとってはうまくいきました。ホストから取得した 401 応答ヘッダーを見て取得できるレルムを提供する必要があります。

val credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY,
  new UsernamePasswordCredentials(user, password));
val authCache = new BasicAuthCache();
val digestScheme = new DigestScheme();

digestScheme.overrideParamter("realm", "**Name of the Realm**");
// Nonce value
digestScheme.overrideParamter("nonce", "whatever");

authCache.put(targetHost, digestScheme);

context.setCredentialsProvider(credsProvider);
context.setAuthCache(authCache);

val httpget = new HttpGet(url);

val response = httpClient.execute(targetHost, httpget, context);
于 2015-04-01T19:26:38.387 に答える
3

digestSchemeコードを確認した後、ダイジェストログインを行うことができました。

digestAuth.processChallenge(null);

以前の入力パラメーターを強制的に解釈します。null パラメータは、送信されたヘッダーに基づくヘッダーです (存在する場合)。

現在 qop/ncは使用されており、必要に応じて digestScheme が機能します。アンドロイドで実行する

digestAuth.overrideParamter("algorithm", "MD5");
digestAuth.overrideParamter("realm", serverRealm);
digestAuth.overrideParamter("nonce", Long.toString(new Random().nextLong(), 36));
digestAuth.overrideParamter("qop", "auth");//   not effective 
digestAuth.overrideParamter("nc",""+sequence);//nt effective 
digestAuth.overrideParamter("cnonce", DigestScheme.createCnonce());
digestAuth.overrideParamter("opaque","ba897c2f0f3de9c6f52d");
String err;
try
{
    digestAuth.processChallenge(null);
    //force  qop in use  chalange  on return header ????!!!!
}
catch (Exception e)
{ 
    err=e.getLocalizedMessage();
}
于 2011-12-20T08:54:27.900 に答える
-1

あなたたちはそれをとても複雑にします。apache httpclient のドキュメントを読めば、とても簡単です。

protected static void downloadDigest(URL url, FileOutputStream fos)
    throws IOException {
    HttpHost targetHost = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());
    CloseableHttpClient httpClient = HttpClients.createDefault();
    HttpClientContext context = HttpClientContext.create();

    String credential = url.getUserInfo();
    if (credential != null) {
        String user = credential.split(":")[0];
        String password = credential.split(":")[1];

        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(AuthScope.ANY,
            new UsernamePasswordCredentials(user, password));
        AuthCache authCache = new BasicAuthCache();
        DigestScheme digestScheme = new DigestScheme();
        authCache.put(targetHost, digestScheme);

        context.setCredentialsProvider(credsProvider);
        context.setAuthCache(authCache);
    }

    HttpGet httpget = new HttpGet(url.getPath());

    CloseableHttpResponse response = httpClient.execute(targetHost, httpget, context);

    try {
        ReadableByteChannel rbc = Channels.newChannel(response.getEntity().getContent());
        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
    } finally {
        response.close();
    }
}
于 2014-11-21T20:36:46.100 に答える