KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > authenticator > BasicAuthenticator


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18
19 package org.apache.catalina.authenticator;
20
21
22 import java.io.IOException JavaDoc;
23 import java.security.Principal JavaDoc;
24
25 import javax.servlet.http.HttpServletResponse JavaDoc;
26
27 import org.apache.catalina.connector.Request;
28 import org.apache.catalina.connector.Response;
29 import org.apache.catalina.deploy.LoginConfig;
30 import org.apache.catalina.util.Base64;
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.tomcat.util.buf.ByteChunk;
34 import org.apache.tomcat.util.buf.CharChunk;
35 import org.apache.tomcat.util.buf.MessageBytes;
36
37
38
39 /**
40  * An <b>Authenticator</b> and <b>Valve</b> implementation of HTTP BASIC
41  * Authentication, as outlined in RFC 2617: "HTTP Authentication: Basic
42  * and Digest Access Authentication."
43  *
44  * @author Craig R. McClanahan
45  * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
46  */

47
48 public class BasicAuthenticator
49     extends AuthenticatorBase {
50     private static Log log = LogFactory.getLog(BasicAuthenticator.class);
51
52
53
54     /**
55      * Authenticate bytes.
56      */

57     public static final byte[] AUTHENTICATE_BYTES = {
58         (byte) 'W',
59         (byte) 'W',
60         (byte) 'W',
61         (byte) '-',
62         (byte) 'A',
63         (byte) 'u',
64         (byte) 't',
65         (byte) 'h',
66         (byte) 'e',
67         (byte) 'n',
68         (byte) 't',
69         (byte) 'i',
70         (byte) 'c',
71         (byte) 'a',
72         (byte) 't',
73         (byte) 'e'
74     };
75
76
77    // ----------------------------------------------------- Instance Variables
78

79
80     /**
81      * Descriptive information about this implementation.
82      */

83     protected static final String JavaDoc info =
84         "org.apache.catalina.authenticator.BasicAuthenticator/1.0";
85
86
87     // ------------------------------------------------------------- Properties
88

89
90     /**
91      * Return descriptive information about this Valve implementation.
92      */

93     public String JavaDoc getInfo() {
94
95         return (info);
96
97     }
98
99
100     // --------------------------------------------------------- Public Methods
101

102
103     /**
104      * Authenticate the user making this request, based on the specified
105      * login configuration. Return <code>true</code> if any specified
106      * constraint has been satisfied, or <code>false</code> if we have
107      * created a response challenge already.
108      *
109      * @param request Request we are processing
110      * @param response Response we are creating
111      * @param config Login configuration describing how authentication
112      * should be performed
113      *
114      * @exception IOException if an input/output error occurs
115      */

116     public boolean authenticate(Request request,
117                                 Response JavaDoc response,
118                                 LoginConfig config)
119         throws IOException JavaDoc {
120
121         // Have we already authenticated someone?
122
Principal JavaDoc principal = request.getUserPrincipal();
123         String JavaDoc ssoId = (String JavaDoc) request.getNote(Constants.REQ_SSOID_NOTE);
124         if (principal != null) {
125             if (log.isDebugEnabled())
126                 log.debug("Already authenticated '" + principal.getName() + "'");
127             // Associate the session with any existing SSO session
128
if (ssoId != null)
129                 associate(ssoId, request.getSessionInternal(true));
130             return (true);
131         }
132
133         // Is there an SSO session against which we can try to reauthenticate?
134
if (ssoId != null) {
135             if (log.isDebugEnabled())
136                 log.debug("SSO Id " + ssoId + " set; attempting " +
137                           "reauthentication");
138             /* Try to reauthenticate using data cached by SSO. If this fails,
139                either the original SSO logon was of DIGEST or SSL (which
140                we can't reauthenticate ourselves because there is no
141                cached username and password), or the realm denied
142                the user's reauthentication for some reason.
143                In either case we have to prompt the user for a logon */

144             if (reauthenticateFromSSO(ssoId, request))
145                 return true;
146         }
147
148         // Validate any credentials already included with this request
149
String JavaDoc username = null;
150         String JavaDoc password = null;
151
152         MessageBytes authorization =
153             request.getCoyoteRequest().getMimeHeaders()
154             .getValue("authorization");
155         
156         if (authorization != null) {
157             authorization.toBytes();
158             ByteChunk authorizationBC = authorization.getByteChunk();
159             if (authorizationBC.startsWithIgnoreCase("basic ", 0)) {
160                 authorizationBC.setOffset(authorizationBC.getOffset() + 6);
161                 // FIXME: Add trimming
162
// authorizationBC.trim();
163

164                 CharChunk authorizationCC = authorization.getCharChunk();
165                 Base64.decode(authorizationBC, authorizationCC);
166                 
167                 // Get username and password
168
int colon = authorizationCC.indexOf(':');
169                 if (colon < 0) {
170                     username = authorizationCC.toString();
171                 } else {
172                     char[] buf = authorizationCC.getBuffer();
173                     username = new String JavaDoc(buf, 0, colon);
174                     password = new String JavaDoc(buf, colon + 1,
175                             authorizationCC.getEnd() - colon - 1);
176                 }
177                 
178                 authorizationBC.setOffset(authorizationBC.getOffset() - 6);
179             }
180
181             principal = context.getRealm().authenticate(username, password);
182             if (principal != null) {
183                 register(request, response, principal, Constants.BASIC_METHOD,
184                          username, password);
185                 return (true);
186             }
187         }
188         
189
190         // Send an "unauthorized" response and an appropriate challenge
191
MessageBytes authenticate =
192             response.getCoyoteResponse().getMimeHeaders()
193             .addValue(AUTHENTICATE_BYTES, 0, AUTHENTICATE_BYTES.length);
194         CharChunk authenticateCC = authenticate.getCharChunk();
195         authenticateCC.append("Basic realm=\"");
196         if (config.getRealmName() == null) {
197             authenticateCC.append(request.getServerName());
198             authenticateCC.append(':');
199             authenticateCC.append(Integer.toString(request.getServerPort()));
200         } else {
201             authenticateCC.append(config.getRealmName());
202         }
203         authenticateCC.append('\"');
204         authenticate.toChars();
205         response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
206         //response.flushBuffer();
207
return (false);
208
209     }
210
211
212 }
213
Popular Tags