KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > controller > jmx > AuthenticatingMBeanServer


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2004 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Marc Wick.
22  * Contributor(s): ______________________.
23  */

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

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

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

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