Home » geronimo-2.2-source-release » org.apache.geronimo.security.realm.providers » [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   package org.apache.geronimo.security.realm.providers;
   18   
   19   import java.io.File;
   20   import java.io.FileOutputStream;
   21   import java.io.IOException;
   22   import java.io.PrintWriter;
   23   import java.nio.channels.FileChannel;
   24   import java.nio.channels.FileLock;
   25   import java.text.DateFormat;
   26   import java.text.SimpleDateFormat;
   27   import java.util.Arrays;
   28   import java.util.Collections;
   29   import java.util.Date;
   30   import java.util.List;
   31   import java.util.Map;
   32   import javax.security.auth.Subject;
   33   import javax.security.auth.callback.Callback;
   34   import javax.security.auth.callback.CallbackHandler;
   35   import javax.security.auth.callback.NameCallback;
   36   import javax.security.auth.login.LoginException;
   37   import javax.security.auth.spi.LoginModule;
   38   
   39   import org.slf4j.Logger;
   40   import org.slf4j.LoggerFactory;
   41   import org.apache.geronimo.security.jaas.JaasLoginModuleUse;
   42   import org.apache.geronimo.security.jaas.WrappingLoginModule;
   43   import org.apache.geronimo.system.serverinfo.ServerInfo;
   44   
   45   /**
   46    * Writes audit records to a file for all authentication activity.  Currently
   47    * doesn't perform too well; perhaps the file management should be centralized
   48    * and the IO objects kept open across many requests.  It would also be nice
   49    * to write in a more convenient XML format.
   50    *
   51    * This module does not write any Principals into the Subject.
   52    *
   53    * To enable this login module, set your primary login module to REQUIRED or
   54    * OPTIONAL, and list this module after it (with any setting).
   55    *
   56    * This login module does not check credentials so it should never be able to cause a login to succeed.
   57    * Therefore the lifecycle methods must return false to indicate success or throw a LoginException to indicate failure.
   58    *
   59    * @version $Rev: 653740 $ $Date: 2008-05-06 03:44:18 -0700 (Tue, 06 May 2008) $
   60    */
   61   public class FileAuditLoginModule implements LoginModule {
   62       private static final Logger log = LoggerFactory.getLogger(FileAuditLoginModule.class);
   63   
   64       public static final String LOG_FILE_OPTION = "file";
   65       public final static List<String> supportedOptions = Collections.unmodifiableList(Arrays.asList(LOG_FILE_OPTION));
   66   
   67       private final static DateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
   68       private File logFile;
   69       private CallbackHandler handler;
   70       private String username;
   71   
   72       public void initialize(Subject subject, CallbackHandler callbackHandler,
   73                              Map sharedState, Map options) {
   74           for(Object option: options.keySet()) {
   75               if(!supportedOptions.contains(option) && !JaasLoginModuleUse.supportedOptions.contains(option)
   76                       && !WrappingLoginModule.supportedOptions.contains(option)) {
   77                   log.warn("Ignoring option: "+option+". Not supported.");
   78               }
   79           }
   80           String name = (String) options.get(LOG_FILE_OPTION);
   81           ServerInfo info = (ServerInfo) options.get(JaasLoginModuleUse.SERVERINFO_LM_OPTION);
   82           logFile = info.resolve(name);
   83           handler = callbackHandler;
   84       }
   85   
   86       public boolean login() throws LoginException {
   87           NameCallback user = new NameCallback("User name:");
   88           Callback[] callbacks = new Callback[]{user};
   89           try {
   90               handler.handle(callbacks);
   91           } catch (Exception e) {
   92               throw (LoginException)new LoginException("Unable to process callback: "+e.getMessage()).initCause(e);
   93           }
   94           if(callbacks.length != 1) {
   95               throw new IllegalStateException("Number of callbacks changed by server!");
   96           }
   97           user = (NameCallback) callbacks[0];
   98           username = user.getName();
   99           writeToFile("Authentication attempt");
  100   
  101           return false;
  102       }
  103   
  104       private synchronized void writeToFile(String action) {
  105           Date date = new Date();
  106           try {
  107               FileOutputStream out = new FileOutputStream(logFile, true);
  108               FileChannel channel = out.getChannel();
  109               FileLock lock = channel.lock(0, Long.MAX_VALUE, false);
  110               PrintWriter writer = new PrintWriter(out, false);
  111               writer.println(DATE_FORMAT.format(date)+" - "+action+" - "+username);
  112               writer.flush();
  113               writer.close();
  114               if(lock.isValid()) {
  115                   lock.release();
  116               }
  117           } catch (IOException e) {
  118               throw new RuntimeException("Unable to write to authentication log file", e);
  119           }
  120       }
  121   
  122       public boolean commit() throws LoginException {
  123           if(username != null) {
  124               writeToFile("Authentication succeeded");
  125           }
  126           return false;
  127       }
  128   
  129       public boolean abort() throws LoginException {
  130           if(username != null) { //work around initial "fake" login
  131               writeToFile("Authentication failed");
  132               username = null;
  133           }
  134           return false;
  135       }
  136   
  137       public boolean logout() throws LoginException {
  138           if(username != null) {
  139               writeToFile("Explicit logout");
  140               username = null;
  141           }
  142           return false;
  143       }
  144   }

Home » geronimo-2.2-source-release » org.apache.geronimo.security.realm.providers » [javadoc | source]