1 /* 2 * $Source$ 3 * $Revision$ 4 * 5 * Copyright (C) 2000 William Chesters 6 * 7 * Part of Melati (http://melati.org), a framework for the rapid 8 * development of clean, maintainable web applications. 9 * 10 * Melati is free software; Permission is granted to copy, distribute 11 * and/or modify this software under the terms either: 12 * 13 * a) the GNU General Public License as published by the Free Software 14 * Foundation; either version 2 of the License, or (at your option) 15 * any later version, 16 * 17 * or 18 * 19 * b) any version of the Melati Software License, as published 20 * at http://melati.org 21 * 22 * You should have received a copy of the GNU General Public License and 23 * the Melati Software License along with this program; 24 * if not, write to the Free Software Foundation, Inc., 25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the 26 * GNU General Public License and visit http://melati.org to obtain the 27 * Melati Software License. 28 * 29 * Feel free to contact the Developers of Melati (http://melati.org), 30 * if you would like to work out a different arrangement than the options 31 * outlined here. It is our intention to allow Melati to be used by as 32 * wide an audience as possible. 33 * 34 * This program is distributed in the hope that it will be useful, 35 * but WITHOUT ANY WARRANTY; without even the implied warranty of 36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37 * GNU General Public License for more details. 38 * 39 * Contact details for copyright holder: 40 * 41 * William Chesters <williamc At paneris.org> 42 * http://paneris.org/~williamc 43 * Obrechtstraat 114, 2517VX Den Haag, The Netherlands 44 */ 45 46 package org.melati.login; 47 48 import javax.servlet.http.HttpServletRequest; 49 50 import org.apache.commons.codec.binary.Base64; 51 52 53 /** 54 * The information contained in an HTTP authorization. 55 * 56 * See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html and 57 * http://www.ietf.org/rfc/rfc2617.txt 58 */ 59 final class HttpAuthorization { 60 String type; 61 String username; 62 String password; 63 64 private HttpAuthorization() { 65 // Utility classes should not have a public or default constructor. 66 } 67 68 /** 69 * Private constructor. 70 * 71 * @param type Authorization type - assumed to be "Basic" 72 * @param username user name to check 73 * @param password user password 74 */ 75 private HttpAuthorization(String type, String username, String password) { 76 this.type = type; 77 this.username = username; 78 this.password = password; 79 } 80 81 /** 82 * Create an Authorization from an HTTP Authorization header. 83 * 84 * @param authHeader 85 * @return a new Authorization or null 86 */ 87 static HttpAuthorization from(String authHeader) { 88 // Space is only valid separator, 89 // from my reading of http://www.ietf.org/rfc/rfc2617.txt 90 // only one. 91 // This has worked well for a long time. 92 if (authHeader.regionMatches(0, "Basic ", 0, 6)) { 93 94 String logpas = new String(Base64.decodeBase64( 95 authHeader.substring(6).getBytes())); 96 97 int colon = logpas.indexOf(':'); 98 99 if (colon == -1) 100 throw new HttpAuthorizationMelatiException( 101 "The browser sent Basic Authorization credentials with no colon " + 102 "(that's not legal)"); 103 104 return new HttpAuthorization("Basic", 105 logpas.substring(0, colon).trim(), 106 logpas.substring(colon + 1).trim()); 107 } 108 else { 109 int space = authHeader.indexOf(' '); 110 if (space == -1) 111 throw new HttpAuthorizationMelatiException( 112 "The browser sent an Authorization header without a space, " + 113 "so it can't be anything Melati understands: " + 114 authHeader); 115 116 String type = authHeader.substring(0, space); 117 throw new HttpAuthorizationMelatiException( 118 "The browser tried to authenticate using an authorization type " + 119 "`" + type + "' which Melati doesn't understand"); 120 } 121 } 122 123 /** 124 * Create an Authorization from a request. 125 * 126 * @param request to extract Authorization header from 127 * @return a new Authorization or null 128 */ 129 static HttpAuthorization from(HttpServletRequest request) { 130 String header = request.getHeader("Authorization"); 131 return header == null ? null : from(header); 132 } 133 } 134