/*
 * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.net.httpserver;

BasicAuthenticator provides an implementation of HTTP Basic authentication. It is an abstract class and must be extended to provide an implementation of checkCredentials(String, String) which is called to verify each incoming request.
/** * BasicAuthenticator provides an implementation of HTTP Basic * authentication. It is an abstract class and must be extended * to provide an implementation of {@link #checkCredentials(String,String)} * which is called to verify each incoming request. */
public abstract class BasicAuthenticator extends Authenticator { protected String realm;
Creates a BasicAuthenticator for the given HTTP realm
Params:
  • realm – The HTTP Basic authentication realm
Throws:
/** * Creates a BasicAuthenticator for the given HTTP realm * @param realm The HTTP Basic authentication realm * @throws NullPointerException if the realm is an empty string */
public BasicAuthenticator (String realm) { this.realm = realm; }
returns the realm this BasicAuthenticator was created with
Returns:the authenticator's realm string.
/** * returns the realm this BasicAuthenticator was created with * @return the authenticator's realm string. */
public String getRealm () { return realm; } public Result authenticate (HttpExchange t) { Headers rmap = t.getRequestHeaders(); /* * look for auth token */ String auth = rmap.getFirst ("Authorization"); if (auth == null) { Headers map = t.getResponseHeaders(); map.set ("WWW-Authenticate", "Basic realm=" + "\""+realm+"\""); return new Authenticator.Retry (401); } int sp = auth.indexOf (' '); if (sp == -1 || !auth.substring(0, sp).equals ("Basic")) { return new Authenticator.Failure (401); } byte[] b = Base64.base64ToByteArray (auth.substring(sp+1)); String userpass = new String (b); int colon = userpass.indexOf (':'); String uname = userpass.substring (0, colon); String pass = userpass.substring (colon+1); if (checkCredentials (uname, pass)) { return new Authenticator.Success ( new HttpPrincipal ( uname, realm ) ); } else { /* reject the request again with 401 */ Headers map = t.getResponseHeaders(); map.set ("WWW-Authenticate", "Basic realm=" + "\""+realm+"\""); return new Authenticator.Failure(401); } }
called for each incoming request to verify the given name and password in the context of this Authenticator's realm. Any caching of credentials must be done by the implementation of this method
Params:
  • username – the username from the request
  • password – the password from the request
Returns:true if the credentials are valid, false otherwise.
/** * called for each incoming request to verify the * given name and password in the context of this * Authenticator's realm. Any caching of credentials * must be done by the implementation of this method * @param username the username from the request * @param password the password from the request * @return <code>true</code> if the credentials are valid, * <code>false</code> otherwise. */
public abstract boolean checkCredentials (String username, String password); } class Base64 {
Translates the specified byte array into a Base64 string as per Preferences.put(byte[]).
/** * Translates the specified byte array into a Base64 string as per * Preferences.put(byte[]). */
static String byteArrayToBase64(byte[] a) { return byteArrayToBase64(a, false); }
Translates the specified byte array into an "aternate representation" Base64 string. This non-standard variant uses an alphabet that does not contain the uppercase alphabetic characters, which makes it suitable for use in situations where case-folding occurs.
/** * Translates the specified byte array into an "aternate representation" * Base64 string. This non-standard variant uses an alphabet that does * not contain the uppercase alphabetic characters, which makes it * suitable for use in situations where case-folding occurs. */
static String byteArrayToAltBase64(byte[] a) { return byteArrayToBase64(a, true); } private static String byteArrayToBase64(byte[] a, boolean alternate) { int aLen = a.length; int numFullGroups = aLen/3; int numBytesInPartialGroup = aLen - 3*numFullGroups; int resultLen = 4*((aLen + 2)/3); StringBuffer result = new StringBuffer(resultLen); char[] intToAlpha = (alternate ? intToAltBase64 : intToBase64); // Translate all full groups from byte array elements to Base64 int inCursor = 0; for (int i=0; i<numFullGroups; i++) { int byte0 = a[inCursor++] & 0xff; int byte1 = a[inCursor++] & 0xff; int byte2 = a[inCursor++] & 0xff; result.append(intToAlpha[byte0 >> 2]); result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]); result.append(intToAlpha[(byte1 << 2)&0x3f | (byte2 >> 6)]); result.append(intToAlpha[byte2 & 0x3f]); } // Translate partial group if present if (numBytesInPartialGroup != 0) { int byte0 = a[inCursor++] & 0xff; result.append(intToAlpha[byte0 >> 2]); if (numBytesInPartialGroup == 1) { result.append(intToAlpha[(byte0 << 4) & 0x3f]); result.append("=="); } else { // assert numBytesInPartialGroup == 2; int byte1 = a[inCursor++] & 0xff; result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]); result.append(intToAlpha[(byte1 << 2)&0x3f]); result.append('='); } } // assert inCursor == a.length; // assert result.length() == resultLen; return result.toString(); }
This array is a lookup table that translates 6-bit positive integer index values into their "Base64 Alphabet" equivalents as specified in Table 1 of RFC 2045.
/** * This array is a lookup table that translates 6-bit positive integer * index values into their "Base64 Alphabet" equivalents as specified * in Table 1 of RFC 2045. */
private static final char intToBase64[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };
This array is a lookup table that translates 6-bit positive integer index values into their "Alternate Base64 Alphabet" equivalents. This is NOT the real Base64 Alphabet as per in Table 1 of RFC 2045. This alternate alphabet does not use the capital letters. It is designed for use in environments where "case folding" occurs.
/** * This array is a lookup table that translates 6-bit positive integer * index values into their "Alternate Base64 Alphabet" equivalents. * This is NOT the real Base64 Alphabet as per in Table 1 of RFC 2045. * This alternate alphabet does not use the capital letters. It is * designed for use in environments where "case folding" occurs. */
private static final char intToAltBase64[] = { '!', '"', '#', '$', '%', '&', '\'', '(', ')', ',', '-', '.', ':', ';', '<', '>', '@', '[', ']', '^', '`', '_', '{', '|', '}', '~', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '?' };
Translates the specified Base64 string (as per Preferences.get(byte[])) into a byte array.
@throwIllegalArgumentException if s is not a valid Base64 string.
/** * Translates the specified Base64 string (as per Preferences.get(byte[])) * into a byte array. * * @throw IllegalArgumentException if <tt>s</tt> is not a valid Base64 * string. */
static byte[] base64ToByteArray(String s) { return base64ToByteArray(s, false); }
Translates the specified "aternate representation" Base64 string into a byte array.
@throwIllegalArgumentException or ArrayOutOfBoundsException if s is not a valid alternate representation Base64 string.
/** * Translates the specified "aternate representation" Base64 string * into a byte array. * * @throw IllegalArgumentException or ArrayOutOfBoundsException * if <tt>s</tt> is not a valid alternate representation * Base64 string. */
static byte[] altBase64ToByteArray(String s) { return base64ToByteArray(s, true); } private static byte[] base64ToByteArray(String s, boolean alternate) { byte[] alphaToInt = (alternate ? altBase64ToInt : base64ToInt); int sLen = s.length(); int numGroups = sLen/4; if (4*numGroups != sLen) throw new IllegalArgumentException( "String length must be a multiple of four."); int missingBytesInLastGroup = 0; int numFullGroups = numGroups; if (sLen != 0) { if (s.charAt(sLen-1) == '=') { missingBytesInLastGroup++; numFullGroups--; } if (s.charAt(sLen-2) == '=') missingBytesInLastGroup++; } byte[] result = new byte[3*numGroups - missingBytesInLastGroup]; // Translate all full groups from base64 to byte array elements int inCursor = 0, outCursor = 0; for (int i=0; i<numFullGroups; i++) { int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt); int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt); int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt); int ch3 = base64toInt(s.charAt(inCursor++), alphaToInt); result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); result[outCursor++] = (byte) ((ch2 << 6) | ch3); } // Translate partial group, if present if (missingBytesInLastGroup != 0) { int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt); int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt); result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); if (missingBytesInLastGroup == 1) { int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt); result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); } } // assert inCursor == s.length()-missingBytesInLastGroup; // assert outCursor == result.length; return result; }
Translates the specified character, which is assumed to be in the "Base 64 Alphabet" into its equivalent 6-bit positive integer.
@throwIllegalArgumentException or ArrayOutOfBoundsException if c is not in the Base64 Alphabet.
/** * Translates the specified character, which is assumed to be in the * "Base 64 Alphabet" into its equivalent 6-bit positive integer. * * @throw IllegalArgumentException or ArrayOutOfBoundsException if * c is not in the Base64 Alphabet. */
private static int base64toInt(char c, byte[] alphaToInt) { int result = alphaToInt[c]; if (result < 0) throw new IllegalArgumentException("Illegal character " + c); return result; }
This array is a lookup table that translates unicode characters drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045) into their 6-bit positive integer equivalents. Characters that are not in the Base64 alphabet but fall within the bounds of the array are translated to -1.
/** * This array is a lookup table that translates unicode characters * drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045) * into their 6-bit positive integer equivalents. Characters that * are not in the Base64 alphabet but fall within the bounds of the * array are translated to -1. */
private static final byte base64ToInt[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 };
This array is the analogue of base64ToInt, but for the nonstandard variant that avoids the use of uppercase alphabetic characters.
/** * This array is the analogue of base64ToInt, but for the nonstandard * variant that avoids the use of uppercase alphabetic characters. */
private static final byte altBase64ToInt[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, 62, 9, 10, 11, -1 , 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 12, 13, 14, -1, 15, 63, 16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, -1, 18, 19, 21, 20, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 22, 23, 24, 25 }; }