001: /**
002: * EasyBeans
003: * Copyright (C) 2006 Bull S.A.S.
004: * Contact: easybeans@ow2.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: JOnASSecurityContext.java 1970 2007-10-16 11:49:25Z benoitf $
023: * --------------------------------------------------------------------------
024: */package org.ow2.easybeans.security.propagation.jonas;
025:
026: import java.lang.reflect.InvocationTargetException;
027: import java.lang.reflect.Method;
028: import java.security.Principal;
029: import java.security.acl.Group;
030:
031: import javax.security.auth.Subject;
032:
033: import org.ow2.easybeans.security.api.EZBSecurityContext;
034: import org.ow2.easybeans.security.struct.JPrincipal;
035:
036: /**
037: * Wrapper class for the JOnAS security.<br>
038: * It will propagate and read JOnAS security context.
039: * @author Florent Benoit
040: */
041: public class JOnASSecurityContext implements EZBSecurityContext {
042:
043: /**
044: * Wrapped security context of JOnAS.
045: */
046: private Object jonasSecurityContext = null;
047:
048: /**
049: * Builds a security context around JOnAS security context.
050: * @param jonasSecurityContext the JOnAS context
051: */
052: public JOnASSecurityContext(final Object jonasSecurityContext) {
053: this .jonasSecurityContext = jonasSecurityContext;
054: }
055:
056: /**
057: * Gets the caller's principal.
058: * @param runAsBean if true, the bean is a run-as bean.
059: * @return principal of the caller.
060: */
061: public Principal getCallerPrincipal(final boolean runAsBean) {
062: Method m = null;
063: try {
064: m = jonasSecurityContext.getClass()
065: .getMethod("getCallerPrincipal",
066: new Class[] { boolean.class });
067: } catch (SecurityException e) {
068: throw new IllegalStateException(
069: "Cannot get the method getCallerPrincipal on the JOnAS security context",
070: e);
071: } catch (NoSuchMethodException e) {
072: throw new IllegalStateException(
073: "Cannot get the method getCallerPrincipal on the JOnAS security context",
074: e);
075: }
076:
077: try {
078: return (Principal) m.invoke(jonasSecurityContext, Boolean
079: .valueOf(runAsBean));
080: } catch (IllegalArgumentException e) {
081: throw new IllegalStateException(
082: "Cannot call getCallerPrincipal method on the JOnAS security context",
083: e);
084: } catch (IllegalAccessException e) {
085: throw new IllegalStateException(
086: "Cannot call getCallerPrincipal method on the JOnAS security context",
087: e);
088: } catch (InvocationTargetException e) {
089: throw new IllegalStateException(
090: "Cannot call getCallerPrincipal method on the JOnAS security context",
091: e);
092: }
093: }
094:
095: /**
096: * Gets the caller's roles.
097: * @param runAsBean if true, the bean is a run-as bean.
098: * @return array of roles of the caller.
099: */
100: public Principal[] getCallerRoles(final boolean runAsBean) {
101: Method m = null;
102: try {
103: m = jonasSecurityContext.getClass().getMethod(
104: "getCallerPrincipalRoles",
105: new Class[] { boolean.class });
106: } catch (SecurityException e) {
107: throw new IllegalStateException(
108: "Cannot get the method getCallerPrincipalRoles on the JOnAS security context",
109: e);
110: } catch (NoSuchMethodException e) {
111: throw new IllegalStateException(
112: "Cannot get the method getCallerPrincipalRoles on the JOnAS security context",
113: e);
114: }
115:
116: String[] roles = null;
117: try {
118: roles = (String[]) m.invoke(jonasSecurityContext, Boolean
119: .valueOf(runAsBean));
120: } catch (IllegalArgumentException e) {
121: throw new IllegalStateException(
122: "Cannot call getCallerPrincipalRoles method on the JOnAS security context",
123: e);
124: } catch (IllegalAccessException e) {
125: throw new IllegalStateException(
126: "Cannot call getCallerPrincipalRoles method on the JOnAS security context",
127: e);
128: } catch (InvocationTargetException e) {
129: throw new IllegalStateException(
130: "Cannot call getCallerPrincipalRoles method on the JOnAS security context",
131: e);
132: }
133:
134: if (roles == null) {
135: throw new IllegalStateException(
136: "No roles found on the JOnAS security context");
137: }
138:
139: Principal[] principals = new Principal[roles.length];
140: int i = 0;
141: for (String role : roles) {
142: principals[i++] = new JPrincipal(role);
143: }
144: return principals;
145: }
146:
147: /**
148: * Enters in run-as mode with the given subject.<br>
149: * The previous subject is stored and will be restored when run-as mode will
150: * be ended.
151: * @param runAsSubject the subject to used in run-as mode.
152: * @return the previous subject.
153: */
154: public Subject enterRunAs(final Subject runAsSubject) {
155:
156: Method m = null;
157: try {
158: m = jonasSecurityContext.getClass().getMethod(
159: "pushRunAs",
160: new Class[] { String.class, String.class,
161: String[].class });
162: } catch (SecurityException e) {
163: throw new IllegalStateException(
164: "Cannot get the method pushRunAs on the JOnAS security context",
165: e);
166: } catch (NoSuchMethodException e) {
167: throw new IllegalStateException(
168: "Cannot get the method pushRunAs on the JOnAS security context",
169: e);
170: }
171:
172: // Get principal name from subject
173: String principalName = null;
174: for (Principal principal : runAsSubject
175: .getPrincipals(Principal.class)) {
176: if (!(principal instanceof Group)) {
177: principalName = principal.getName();
178: break;
179: }
180: }
181:
182: // Get role from subject
183: String role = null;
184: for (Principal principal : runAsSubject
185: .getPrincipals(Principal.class)) {
186: if (principal instanceof Group) {
187: role = ((Group) principal).members().nextElement()
188: .getName();
189: }
190: }
191:
192: try {
193: m.invoke(jonasSecurityContext, role, principalName,
194: new String[] { role });
195: } catch (IllegalArgumentException e) {
196: throw new IllegalStateException(
197: "Cannot call pushRunAs method on the JOnAS security context",
198: e);
199: } catch (IllegalAccessException e) {
200: throw new IllegalStateException(
201: "Cannot call pushRunAs method on the JOnAS security context",
202: e);
203: } catch (InvocationTargetException e) {
204: throw new IllegalStateException(
205: "Cannot call pushRunAs method on the JOnAS security context",
206: e);
207: }
208:
209: // Not used with JOnAS security context
210: return null;
211:
212: }
213:
214: /**
215: * Ends the run-as mode and then restore the context stored by container.
216: * @param oldSubject subject kept by container and restored.
217: */
218: public void endsRunAs(final Subject oldSubject) {
219: Method m = null;
220: try {
221: m = jonasSecurityContext.getClass().getMethod("popRunAs");
222: } catch (SecurityException e) {
223: throw new IllegalStateException(
224: "Cannot get the method popRunAs on the JOnAS security context",
225: e);
226: } catch (NoSuchMethodException e) {
227: throw new IllegalStateException(
228: "Cannot get the method popRunAs on the JOnAS security context",
229: e);
230: }
231:
232: try {
233: m.invoke(jonasSecurityContext);
234: } catch (IllegalArgumentException e) {
235: throw new IllegalStateException(
236: "Cannot call popRunAs method on the JOnAS security context",
237: e);
238: } catch (IllegalAccessException e) {
239: throw new IllegalStateException(
240: "Cannot call popRunAs method on the JOnAS security context",
241: e);
242: } catch (InvocationTargetException e) {
243: throw new IllegalStateException(
244: "Cannot call popRunAs method on the JOnAS security context",
245: e);
246: }
247: }
248:
249: }
|