1/* 2 * Copyright (C) 2013 Square, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.squareup.okhttp; 17 18import java.io.IOException; 19import java.io.UnsupportedEncodingException; 20import java.net.Proxy; 21import java.net.URL; 22import java.util.List; 23import okio.ByteString; 24 25/** 26 * Responds to authentication challenges from the remote web or proxy server by 27 * returning credentials. 28 */ 29public interface OkAuthenticator { 30 /** 31 * Returns a credential that satisfies the authentication challenge made by 32 * {@code url}. Returns null if the challenge cannot be satisfied. This method 33 * is called in response to an HTTP 401 unauthorized status code sent by the 34 * origin server. 35 * 36 * @param challenges parsed "WWW-Authenticate" challenge headers from the HTTP 37 * response. 38 */ 39 Credential authenticate(Proxy proxy, URL url, List<Challenge> challenges) throws IOException; 40 41 /** 42 * Returns a credential that satisfies the authentication challenge made by 43 * {@code proxy}. Returns null if the challenge cannot be satisfied. This 44 * method is called in response to an HTTP 401 unauthorized status code sent 45 * by the proxy server. 46 * 47 * @param challenges parsed "Proxy-Authenticate" challenge headers from the 48 * HTTP response. 49 */ 50 Credential authenticateProxy(Proxy proxy, URL url, List<Challenge> challenges) throws IOException; 51 52 /** An RFC 2617 challenge. */ 53 public final class Challenge { 54 private final String scheme; 55 private final String realm; 56 57 public Challenge(String scheme, String realm) { 58 this.scheme = scheme; 59 this.realm = realm; 60 } 61 62 /** Returns the authentication scheme, like {@code Basic}. */ 63 public String getScheme() { 64 return scheme; 65 } 66 67 /** Returns the protection space. */ 68 public String getRealm() { 69 return realm; 70 } 71 72 @Override public boolean equals(Object o) { 73 return o instanceof Challenge 74 && ((Challenge) o).scheme.equals(scheme) 75 && ((Challenge) o).realm.equals(realm); 76 } 77 78 @Override public int hashCode() { 79 return scheme.hashCode() + 31 * realm.hashCode(); 80 } 81 82 @Override public String toString() { 83 return scheme + " realm=\"" + realm + "\""; 84 } 85 } 86 87 /** An RFC 2617 credential. */ 88 public final class Credential { 89 private final String headerValue; 90 91 private Credential(String headerValue) { 92 this.headerValue = headerValue; 93 } 94 95 /** Returns an auth credential for the Basic scheme. */ 96 public static Credential basic(String userName, String password) { 97 try { 98 String usernameAndPassword = userName + ":" + password; 99 byte[] bytes = usernameAndPassword.getBytes("ISO-8859-1"); 100 String encoded = ByteString.of(bytes).base64(); 101 return new Credential("Basic " + encoded); 102 } catch (UnsupportedEncodingException e) { 103 throw new AssertionError(); 104 } 105 } 106 107 public String getHeaderValue() { 108 return headerValue; 109 } 110 111 @Override public boolean equals(Object o) { 112 return o instanceof Credential && ((Credential) o).headerValue.equals(headerValue); 113 } 114 115 @Override public int hashCode() { 116 return headerValue.hashCode(); 117 } 118 119 @Override public String toString() { 120 return headerValue; 121 } 122 } 123} 124