HTTPライブラリVolleyでDigest認証を実装してみたという話。誰得感は否めない。
基本的な流れ
- リクエストキューにリクエストを追加する。リクエスト(
Request<T>
を継承したやつ)にはリトライポリシー(RetryPolicy
を継承したやつ)を仕込んでおく(Request<T>#setRetryPolicy()
)。 - 401が返ってくる。この時、
RetryPolicy#retry()
が呼ばれるので、そこで401と一緒に受け取るWWW-Authenticate
ヘッダのパラメータをDigestScheme#processChallenge()
に渡す - ユーザ名とPWを
DigestScheme#authenticate()
に渡してAuthorization
ヘッダを作る。 - オーバライドした
Request<T>#getHeaders()
の中でAuthorization
ヘッダを追加する。
Digest認証やVolley内部の処理の流れなど細かいことはブログに書きました。
2から4までをやるのが下記のコードです。
MyRequest.java
public class MyRequest extends Request<JSONObject> {
// いろいろ略
// コンストラクタとかでDigestRetryPolicyを生成する
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
DigestScheme ds = new DigestScheme();
ds.processChallenge(new BasicHeader("WWW-Authenticate",
mChallengeHeader.get("WWW-Authenticate"));
Header header = ds.authenticate(credencials, request);
Map<String, String> newHeader
= new HashMap<String, String>(super.getHeaders());
newHeader.put(header.getName(), header.getValue());
return newHeader;
}
private Map<String, String> mChallengeHeader;
public void setChallengeHeader(Map<String, String> header) {
this.mChallengeHeader = header;
}
class DigestRetryPolicy extends DefaultRetryPolicy {
@Override
public void retry(VolleyError error) throws VolleyError {
if (error.statusCode == HttpStatus.SC_UNAUTHORIZED) {
setChallengeHeader(error.networkResponse.header);
} else {
super.retry(error);
}
}
}
}