Home » geronimo-2.2-source-release » org.apache.geronimo.jmxremoting » [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.jmxremoting;
   18   
   19   import java.util.Collections;
   20   import java.util.HashMap;
   21   import java.util.Map;
   22   import java.util.Set;
   23   
   24   import javax.management.Notification;
   25   import javax.management.NotificationListener;
   26   import javax.management.remote.JMXAuthenticator;
   27   import javax.management.remote.JMXConnectionNotification;
   28   import javax.security.auth.Subject;
   29   import javax.security.auth.login.LoginContext;
   30   import javax.security.auth.login.LoginException;
   31   
   32   import org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal;
   33   /**
   34    * JMX Authenticator that checks the Credentials by logging in via JAAS.
   35    *
   36    * @version $Rev: 817568 $ $Date: 2009-09-22 02:20:27 -0700 (Tue, 22 Sep 2009) $
   37    */
   38   public class Authenticator implements JMXAuthenticator, NotificationListener {
   39       private final String configName;
   40       private final ClassLoader cl;
   41       private ThreadLocal<LoginContext> threadContext = new ThreadLocal<LoginContext>();
   42       private Map<String, LoginContext> contextMap = Collections.synchronizedMap(new HashMap<String, LoginContext>());
   43   
   44       /**
   45        * Constructor indicating which JAAS Application Configuration Entry to use.
   46        * @param configName the JAAS config name
   47        * @param cl classloader to use as TCCL for operations
   48        */
   49       public Authenticator(String configName, ClassLoader cl) {
   50           this.configName = configName;
   51           this.cl = cl;
   52       }
   53   
   54       public Subject authenticate(Object o) throws SecurityException {
   55           if (!(o instanceof String[])) {
   56               throw new IllegalArgumentException("Expected String[2], got " + (o == null ? null : o.getClass().getName()));
   57           }
   58           String[] params = (String[]) o;
   59           if (params.length != 2) {
   60               throw new IllegalArgumentException("Expected String[2] but length was " + params.length);
   61           }
   62   
   63           Thread thread = Thread.currentThread();
   64           ClassLoader oldCL = thread.getContextClassLoader();
   65           Credentials credentials = new Credentials(params[0], params[1]);
   66           try {
   67               thread.setContextClassLoader(cl);
   68               //TODO consider using ContextManager for login and checking a permission against the ACC
   69               //to do e.g. deployments.
   70               LoginContext context = new LoginContext(configName, credentials);
   71               context.login();
   72               threadContext.set(context);
   73               Subject sub = context.getSubject();
   74               Set<GeronimoGroupPrincipal> pricipalsGroup = sub.getPrincipals(GeronimoGroupPrincipal.class);
   75               boolean isInAdminGroup = false;
   76               for (GeronimoGroupPrincipal principal : pricipalsGroup) {
   77                   if (principal.getName().equals("admin")) {
   78                       isInAdminGroup = true;
   79                       break;
   80                    }
   81               }
   82               if(!isInAdminGroup){
   83                   throw new LoginException("Only users in admin group are allowed");
   84               }
   85               return context.getSubject();
   86           } catch (LoginException e) {
   87               // do not propogate cause - we don't know what information is may contain
   88               throw new SecurityException("Invalid login");
   89           } finally {
   90               credentials.clear();
   91               thread.setContextClassLoader(oldCL);
   92           }
   93       }
   94   
   95       public void handleNotification(Notification notification, Object o) {
   96           if (notification instanceof JMXConnectionNotification) {
   97               JMXConnectionNotification cxNotification = (JMXConnectionNotification) notification;
   98               String type = cxNotification.getType();
   99               String connectionId = cxNotification.getConnectionId();
  100               if (JMXConnectionNotification.OPENED.equals(type)) {
  101                   LoginContext context = threadContext.get();
  102                   threadContext.set(null);
  103                   contextMap.put(connectionId, context);
  104               } else {
  105                   LoginContext context = contextMap.remove(connectionId);
  106                   if (context != null) {
  107                       try {
  108                           context.logout();
  109                       } catch (LoginException e) {
  110                           //nothing we can do here...
  111                       }
  112                   }
  113               }
  114           }
  115       }
  116   }

Home » geronimo-2.2-source-release » org.apache.geronimo.jmxremoting » [javadoc | source]