Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » authenticator » [javadoc | source]
    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;
   23   import java.security.Principal;
   24   
   25   import javax.servlet.http.HttpServletResponse;
   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.juli.logging.Log;
   32   import org.apache.juli.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 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 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 response,
  118                                   LoginConfig config)
  119           throws IOException {
  120   
  121           // Have we already authenticated someone?
  122           Principal principal = request.getUserPrincipal();
  123           String ssoId = (String) 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 username = null;
  150           String 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(buf, 0, colon);
  174                       password = new String(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   }

Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » authenticator » [javadoc | source]