KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > continuent > sequoia > controller > jmx > AuthenticatingMBeanServer


1 /**
2  * Sequoia: Database clustering technology.
3  * Copyright (C) 2002-2004 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: sequoia@continuent.org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * Initial developer(s): Marc Wick.
20  * Contributor(s): ______________________.
21  */

22
23 package org.continuent.sequoia.controller.jmx;
24
25 import java.util.ArrayList JavaDoc;
26 import java.util.Arrays JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.Set JavaDoc;
30
31 import javax.management.InstanceNotFoundException JavaDoc;
32 import javax.management.MBeanException JavaDoc;
33 import javax.management.MBeanServer JavaDoc;
34 import javax.management.ObjectName JavaDoc;
35 import javax.management.ReflectionException JavaDoc;
36 import javax.security.auth.Subject JavaDoc;
37
38 import org.continuent.sequoia.common.jmx.JMXPrincipalWithPassword;
39 import org.continuent.sequoia.common.jmx.JmxConstants;
40 import org.continuent.sequoia.common.log.Trace;
41
42 /**
43  * An MBeanServer authenticating all invoke() requests.
44  *
45  * @author <a HREF="mailto:marc.wick@monte-bre.ch">Marc Wick </a>
46  * @author <a HREF="mailto:nicolas.modrzyk@inrialpes.fr">Nicolas Modrzyk </a>
47  * @version 1.0
48  */

49 public class AuthenticatingMBeanServer extends ChainedMBeanServer
50 {
51
52   /** Logger instance */
53   static Trace logger = Trace
54                           .getLogger("org.continuent.sequoia.controller.jmx.AuthenticatingMBeanServer");
55
56   /**
57    * Overridden just to make it public
58    * <p>
59    *
60    * @see org.continuent.sequoia.controller.jmx.ChainedMBeanServer#setMBeanServer(javax.management.MBeanServer)
61    */

62   public void setMBeanServer(MBeanServer JavaDoc server)
63   {
64     super.setMBeanServer(server);
65   }
66
67   /**
68    * @see javax.management.MBeanServerConnection#invoke(javax.management.ObjectName,
69    * java.lang.String, java.lang.Object[], java.lang.String[])
70    */

71   public Object JavaDoc invoke(ObjectName JavaDoc name, String JavaDoc operationName, Object JavaDoc[] params,
72       String JavaDoc[] signature) throws InstanceNotFoundException JavaDoc, MBeanException JavaDoc,
73       ReflectionException JavaDoc
74   {
75     if (JmxConstants.mbeanNeedAuthentication(name)
76         && (operationName.equalsIgnoreCase("checkAdminAuthentication") == false))
77     {
78       // we have to check all methods that access a virtual database
79
// except
80
// authentication
81
boolean authenticationOk = false;
82       String JavaDoc username = null;
83       String JavaDoc password = null;
84
85       Subject JavaDoc subject = Subject.getSubject(java.security.AccessController
86           .getContext());
87       if (subject == null || subject.getPrincipals().size() == 0)
88       {
89         username = (String JavaDoc) params[0];
90         password = (String JavaDoc) params[1];
91         authenticationOk = authenticate(name, username, password);
92         if (!authenticationOk)
93           throw new MBeanException JavaDoc(new Exception JavaDoc(
94               "Authentication failed (username,password) invalid"));
95
96         if (logger.isDebugEnabled())
97           logger
98               .debug("Authentication with username and password was successfull");
99
100         // we have to strip the username and password from the params
101
// and args
102
return super.invoke(name, operationName, cleanO(params),
103             cleanS(signature));
104       }
105       else
106       {
107         Set JavaDoc principals = subject.getPrincipals(JMXPrincipalWithPassword.class);
108         for (Iterator JavaDoc it = principals.iterator(); it.hasNext();)
109         {
110           JMXPrincipalWithPassword principal = (JMXPrincipalWithPassword) it
111               .next();
112           username = principal.getName();
113           password = principal.getPassword();
114           authenticationOk = authenticate(name, username, password);
115           if (authenticationOk)
116             break;
117         }
118
119         if (principals.size() == 0 && logger.isDebugEnabled())
120           throw new MBeanException JavaDoc(new Exception JavaDoc(
121               "Authentication failed : no principal"));
122
123         if (!authenticationOk)
124           throw new MBeanException JavaDoc(new Exception JavaDoc(
125               "Authentication failed : principal invalid"));
126         if (logger.isDebugEnabled())
127           logger.debug("Authentication with principal was successfull");
128         return super.invoke(name, operationName, params, signature);
129       }
130     }
131     else
132     {
133       if (logger.isDebugEnabled())
134         logger.debug("no authentication required");
135
136       return super.invoke(name, operationName, params, signature);
137     }
138   }
139
140   private boolean authenticate(ObjectName JavaDoc name, String JavaDoc username, String JavaDoc password)
141   {
142     try
143     {
144       String JavaDoc type = name.getKeyProperty("type");
145       boolean vdb = JmxConstants.VIRTUALDATABASE_TYPE_VALUE.equals(type);
146       if (vdb)
147         return ((Boolean JavaDoc) invoke(name, "checkAdminAuthentication",
148             new Object JavaDoc[]{username, password}, new String JavaDoc[]{"java.lang.String",
149                 "java.lang.String"})).booleanValue();
150       else
151       {
152         boolean backend = JmxConstants.DATABASEBACKEND_TYPE_VALUE.equals(type);
153         if (backend)
154         {
155           String JavaDoc virtualDataBaseName = name
156               .getKeyProperty(JmxConstants.VIRTUALDATABASE_PROPERTY);
157           if (virtualDataBaseName == null)
158           {
159             return false;
160           }
161           // Check with the owning database if the password is right
162
ObjectName JavaDoc vdbName = JmxConstants
163               .getVirtualDataBaseObjectName(virtualDataBaseName);
164           return ((Boolean JavaDoc) invoke(vdbName, "checkAdminAuthentication",
165               new Object JavaDoc[]{username, password}, new String JavaDoc[]{
166                   "java.lang.String", "java.lang.String"})).booleanValue();
167         }
168         else
169           // No further check ...
170
return true;
171       }
172     }
173     catch (Exception JavaDoc e)
174     {
175       if (logger.isDebugEnabled())
176       {
177         logger.debug("authentication failed with exception ", e);
178       }
179       return false;
180     }
181   }
182
183   private static Object JavaDoc[] cleanO(Object JavaDoc[] params)
184   {
185     List JavaDoc o = Arrays.asList(params);
186     o = o.subList(2, o.size());
187     return (new ArrayList JavaDoc(o).toArray());
188   }
189
190   private static String JavaDoc[] cleanS(String JavaDoc[] params)
191   {
192     List JavaDoc o = Arrays.asList(params);
193     o = o.subList(2, o.size());
194     String JavaDoc[] s = new String JavaDoc[o.size()];
195     return (String JavaDoc[]) new ArrayList JavaDoc(o).toArray(s);
196   }
197 }
Popular Tags