簡體   English   中英

將HTTP Basic-Auth與Google App Engine URLFetch服務配合使用

[英]Using HTTP Basic-Auth with Google App Engine URLFetch service

如何使用App Engine的URLFetch服務(Java)指定用於制作Basic-Auth請求的用戶名和密碼?

我似乎可以設置HTTP標頭:

URL url = new URL("http://www.example.com/comment");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("X-MyApp-Version", "2.7.3");        

Basic-Auth的適當標題是什么?

這是基於http的基本身份驗證標頭:

授權:基本base64編碼(用戶名:密碼)

例如:

GET /private/index.html HTTP/1.0
Host: myhost.com
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

你需要這樣做:

URL url = new URL("http://www.example.com/comment");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Authorization",
"Basic "+codec.encodeBase64String(("username:password").getBytes());

要做到這一點,你將需要一個base64編解碼器API,如Apache Commons Codec

對於那些有興趣在Python中執行此操作的人(就像我一樣),代碼如下所示:

result = urlfetch.fetch("http://www.example.com/comment",
                        headers={"Authorization": 
                                 "Basic %s" % base64.b64encode("username:pass")})

在調用openConnection()之前設置一個Authenticator,

Authenticator.setDefault(new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(username, password.toCharArray());
    }
});

由於只有一個全局默認驗證器,當多個用戶在多個線程中執行URLFetch時,這實際上不能很好地工作。 如果是這樣的話,我會使用Apache HttpClient。

編輯:我錯了。 App Engine不允許使用Authenticator。 即使允許,我們也會遇到全局驗證器實例的多線程問題。 即使您無法創建線程,您的請求仍可能在不同的線程中提供。 所以我們只需使用此函數手動添加標題,

import com.google.appengine.repackaged.com.google.common.util.Base64;
    /**
     * Preemptively set the Authorization header to use Basic Auth.
     * @param connection The HTTP connection
     * @param username Username
     * @param password Password
     */
    public static void setBasicAuth(HttpURLConnection connection,
            String username, String password) {
        StringBuilder buf = new StringBuilder(username);
        buf.append(':');
        buf.append(password);
        byte[] bytes = null;
        try {
            bytes = buf.toString().getBytes("ISO-8859-1");
        } catch (java.io.UnsupportedEncodingException uee) {
            assert false;
        }

        String header = "Basic " + Base64.encode(bytes);
        connection.setRequestProperty("Authorization", header);
    }

使用HttpURLConnection給了我一些問題(由於某種原因,我嘗試連接的服務器不接受身份驗證憑據),最后我意識到使用GAE的低級URLFetch API( com.google.appengine.api.urlfetch實際上要容易得多。 com.google.appengine.api.urlfetch )喜歡這樣:

URL fetchurl = new URL(url);

String nameAndPassword = credentials.get("name")+":"+credentials.get("password");
String authorizationString = "Basic " + Base64.encode(nameAndPassword.getBytes());

HTTPRequest request = new HTTPRequest(fetchurl);
request.addHeader(new HTTPHeader("Authorization", authorizationString));

HTTPResponse response = URLFetchServiceFactory.getURLFetchService().fetch(request);
System.out.println(new String(response.getContent()));

這很有效。

關於第一個答案的注意事項:setRequestProperty應該獲取沒有冒號的屬性名稱(“授權”而不是“授權:”)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM