001: /*
002: * @(#)BasicAuthentication.java 1.16 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package sun.net.www.protocol.http;
029:
030: import java.net.URL;
031: import java.net.URI;
032: import java.net.URISyntaxException;
033: import java.net.PasswordAuthentication;
034: import sun.net.www.HeaderParser;
035:
036: /**
037: * BasicAuthentication: Encapsulate an http server authentication using
038: * the "basic" scheme.
039: *
040: * @version 1.9, 02/02/00
041: */
042:
043: class BasicAuthentication extends AuthenticationInfo {
044:
045: static final char BASIC_AUTH = 'B';
046:
047: /** The authentication string for this host, port, and realm. This is
048: a simple BASE64 encoding of "login:password". */
049: String auth;
050:
051: /**
052: * Create a BasicAuthentication
053: */
054: public BasicAuthentication(boolean isProxy, String host, int port,
055: String realm, PasswordAuthentication pw) {
056: super (isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
057: BASIC_AUTH, host, port, realm);
058: String plain = pw.getUserName() + ":";
059: byte[] nameBytes = plain.getBytes();
060:
061: // get password bytes
062: char[] passwd = pw.getPassword();
063: byte[] passwdBytes = new byte[passwd.length];
064: for (int i = 0; i < passwd.length; i++)
065: passwdBytes[i] = (byte) passwd[i];
066:
067: // concatenate user name and password bytes and encode them
068: byte[] concat = new byte[nameBytes.length + passwdBytes.length];
069: System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length);
070: System.arraycopy(passwdBytes, 0, concat, nameBytes.length,
071: passwdBytes.length);
072: this .auth = "Basic "
073: + (new sun.misc.BASE64Encoder()).encode(concat);
074: }
075:
076: /**
077: * Create a BasicAuthentication
078: */
079: public BasicAuthentication(boolean isProxy, String host, int port,
080: String realm, String auth) {
081: super (isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
082: BASIC_AUTH, host, port, realm);
083: this .auth = "Basic " + auth;
084: }
085:
086: /**
087: * Create a BasicAuthentication
088: */
089: public BasicAuthentication(boolean isProxy, URL url, String realm,
090: PasswordAuthentication pw) {
091: super (isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
092: BASIC_AUTH, url, realm);
093: String plain = pw.getUserName() + ":";
094: byte[] nameBytes = plain.getBytes();
095:
096: // get password bytes
097: char[] passwd = pw.getPassword();
098: byte[] passwdBytes = new byte[passwd.length];
099: for (int i = 0; i < passwd.length; i++)
100: passwdBytes[i] = (byte) passwd[i];
101:
102: // concatenate user name and password bytes and encode them
103: byte[] concat = new byte[nameBytes.length + passwdBytes.length];
104: System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length);
105: System.arraycopy(passwdBytes, 0, concat, nameBytes.length,
106: passwdBytes.length);
107: this .auth = "Basic "
108: + (new sun.misc.BASE64Encoder()).encode(concat);
109: }
110:
111: /**
112: * Create a BasicAuthentication
113: */
114: public BasicAuthentication(boolean isProxy, URL url, String realm,
115: String auth) {
116: super (isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
117: BASIC_AUTH, url, realm);
118: this .auth = "Basic " + auth;
119: }
120:
121: /**
122: * @return true if this authentication supports preemptive authorization
123: */
124: boolean supportsPreemptiveAuthorization() {
125: return true;
126: }
127:
128: /**
129: * @return the name of the HTTP header this authentication wants set
130: */
131: String getHeaderName() {
132: if (type == SERVER_AUTHENTICATION) {
133: return "Authorization";
134: } else {
135: return "Proxy-authorization";
136: }
137: }
138:
139: /**
140: * Set header(s) on the given connection. This will only be called for
141: * definitive (i.e. non-preemptive) authorization.
142: * @param conn The connection to apply the header(s) to
143: * @param p A source of header values for this connection, if needed.
144: * @param raw The raw header values for this connection, if needed.
145: * @return true if all goes well, false if no headers were set.
146: */
147: boolean setHeaders(HttpURLConnection conn, HeaderParser p,
148: String raw) {
149: conn.setAuthenticationProperty(getHeaderName(), getHeaderValue(
150: null, null));
151: return true;
152: }
153:
154: /**
155: * @return the value of the HTTP header this authentication wants set
156: */
157: String getHeaderValue(URL url, String method) {
158: /* For Basic the authorization string does not depend on the request URL
159: * or the request method
160: */
161: return auth;
162: }
163:
164: /**
165: * For Basic Authentication, the security parameters can never be stale.
166: * In other words there is no possibility to reuse the credentials.
167: * They are always either valid or invalid.
168: */
169: boolean isAuthorizationStale(String header) {
170: return false;
171: }
172:
173: /**
174: * For Basic Authentication, there is no security information in the
175: * response
176: */
177: void checkResponse(String header, String method, URL url) {
178: }
179:
180: /**
181: * @return the common root path between npath and path.
182: * This is used to detect when we have an authentication for two
183: * paths and the root of th authentication space is the common root.
184: */
185:
186: static String getRootPath(String npath, String opath) {
187: int index = 0;
188: int toindex;
189:
190: /* Must normalize so we don't get confused by ../ and ./ segments */
191: try {
192: npath = new URI(npath).normalize().getPath();
193: opath = new URI(opath).normalize().getPath();
194: } catch (URISyntaxException e) {
195: /* ignore error and use the old value */
196: }
197:
198: while (index < opath.length()) {
199: toindex = opath.indexOf('/', index + 1);
200: if (toindex != -1
201: && opath.regionMatches(0, npath, 0, toindex + 1))
202: index = toindex;
203: else
204: return opath.substring(0, index + 1);
205: }
206: /*should not reach here. If we do simply return npath*/
207: return npath;
208: }
209:
210: }
|