Answers a challenge by adding an authentication header to a request. @param rb HTTP request builder @param response HTTP response @return success flag
(final HttpRequest.Builder rb, final HttpResponse<?> response)
| 75 | * @return success flag |
| 76 | */ |
| 77 | public boolean assign(final HttpRequest.Builder rb, final HttpResponse<?> response) { |
| 78 | // no credentials available, server does not expect authentication: skip |
| 79 | if(username == null || password == null || response.statusCode() != 401) return false; |
| 80 | |
| 81 | final String value; |
| 82 | if(request.authMethod == AuthMethod.BASIC) { |
| 83 | value = Base64.encode(username + ':' + password); |
| 84 | } else { |
| 85 | // server provides no authentication data: skip |
| 86 | final Optional<String> header = response.headers().firstValue(WWW_AUTHENTICATE); |
| 87 | if(header.isEmpty()) return false; |
| 88 | // server returns other authentication method: skip |
| 89 | final EnumMap<RequestAttribute, String> auth = Client.authHeaders(header.get()); |
| 90 | if(!auth.get(AUTH_METHOD).equals(request.authMethod.toString())) return false; |
| 91 | |
| 92 | final String realm = |
| 93 | auth.get(REALM), |
| 94 | nonce = auth.get(NONCE), |
| 95 | qop = auth.get(QOP), |
| 96 | nc = "00000001", |
| 97 | cnonce = Strings.md5(Long.toString(System.nanoTime())), |
| 98 | ha1 = Strings.md5(username + ':' + realm + ':' + password), |
| 99 | ha2 = Strings.md5(request.attribute(METHOD) + ':' + uri), |
| 100 | rsp = Strings.md5(ha1 + ':' + nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2); |
| 101 | value = USERNAME + "=\"" + username + "\"," |
| 102 | + REALM + "=\"" + realm + "\"," |
| 103 | + NONCE + "=\"" + nonce + "\"," |
| 104 | + URI + "=\"" + uri + "\"," |
| 105 | + QOP + '=' + qop + ',' |
| 106 | + NC + '=' + nc + ',' |
| 107 | + CNONCE + "=\"" + cnonce + "\"," |
| 108 | + RESPONSE + "=\"" + rsp + "\"," |
| 109 | + ALGORITHM + '=' + MD5 + ',' |
| 110 | + OPAQUE + "=\"" + auth.get(OPAQUE) + '"'; |
| 111 | } |
| 112 | rb.header(AUTHORIZATION, request.authMethod + " " + value); |
| 113 | return true; |
| 114 | } |
| 115 | } |