001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.test.security.ejb;
023:
024: import java.rmi.RemoteException;
025: import java.security.Principal;
026: import java.security.acl.Group;
027: import java.util.Iterator;
028: import java.util.Set;
029: import javax.ejb.SessionContext;
030: import javax.ejb.SessionBean;
031: import javax.ejb.EJBException;
032: import javax.naming.InitialContext;
033: import javax.security.auth.Subject;
034: import javax.security.jacc.PolicyContext;
035: import javax.security.jacc.PolicyContextException;
036:
037: import org.jboss.test.security.interfaces.RunAsServiceRemote;
038: import org.jboss.test.security.interfaces.RunAsServiceRemoteHome;
039: import org.jboss.test.security.interfaces.CallerInfo;
040: import org.jboss.security.SimplePrincipal;
041:
042: /**
043: * A session facade that tests that the security context reflected by the
044: * SecurityAssociation.getSubject and PolicyContext. This will not run under
045: * the security manager tests as ejbs are not granted access to these security
046: * apis.
047: *
048: * @author Scott.Stark@jboss.org
049: * @version $Revision: 57211 $
050: */
051: public class SecuredBean implements SessionBean {
052: /** The JACC PolicyContext key for the current Subject */
053: private static final String SUBJECT_CONTEXT_KEY = "javax.security.auth.Subject.container";
054: private SessionContext context;
055:
056: public void ejbCreate() {
057: }
058:
059: public void ejbActivate() {
060: }
061:
062: public void ejbPassivate() {
063: }
064:
065: public void ejbRemove() {
066: }
067:
068: public void setSessionContext(SessionContext context) {
069: this .context = context;
070: }
071:
072: public void unprotectedEjbMethod(CallerInfo info)
073: throws RemoteException {
074: Principal caller = context.getCallerPrincipal();
075: if (caller.equals(info.getCallerIdentity()) == false)
076: throw new EJBException("getCallerPrincipal(" + caller
077: + ") does not equal CallerIdentity: "
078: + info.getCallerIdentity());
079:
080: validateRoles(info);
081: try {
082: Subject subject = (Subject) PolicyContext
083: .getContext(SUBJECT_CONTEXT_KEY);
084: validateRoles(info, subject);
085: } catch (PolicyContextException e) {
086: throw new EJBException(e);
087: }
088:
089: RunAsServiceRemote bean = getBean();
090: bean.unprotectedEjbMethod(info);
091: }
092:
093: public void runAsMethod(CallerInfo info) throws RemoteException {
094: Principal caller = context.getCallerPrincipal();
095: if (caller.equals(info.getCallerIdentity()) == false)
096: throw new EJBException("getCallerPrincipal(" + caller
097: + ") does not equal CallerIdentity: "
098: + info.getCallerIdentity());
099:
100: validateRoles(info);
101: try {
102: Subject subject = (Subject) PolicyContext
103: .getContext(SUBJECT_CONTEXT_KEY);
104: validateRoles(info, subject);
105: } catch (PolicyContextException e) {
106: throw new EJBException(e);
107: }
108:
109: RunAsServiceRemote bean = getBean();
110: bean.runAsMethod(info);
111: }
112:
113: public void groupMemberMethod(CallerInfo info)
114: throws RemoteException {
115: Principal caller = context.getCallerPrincipal();
116: if (caller.equals(info.getCallerIdentity()) == false)
117: throw new EJBException("getCallerPrincipal(" + caller
118: + ") does not equal CallerIdentity: "
119: + info.getCallerIdentity());
120:
121: validateRoles(info);
122: try {
123: Subject subject = (Subject) PolicyContext
124: .getContext(SUBJECT_CONTEXT_KEY);
125: validateRoles(info, subject);
126: } catch (PolicyContextException e) {
127: throw new EJBException(e);
128: }
129:
130: RunAsServiceRemote bean = getBean();
131: bean.groupMemberMethod(info);
132: }
133:
134: public void userMethod(CallerInfo info) throws RemoteException {
135: Principal caller = context.getCallerPrincipal();
136: if (caller.equals(info.getCallerIdentity()) == false)
137: throw new EJBException("getCallerPrincipal(" + caller
138: + ") does not equal CallerIdentity: "
139: + info.getCallerIdentity());
140:
141: validateRoles(info);
142: try {
143: Subject subject = (Subject) PolicyContext
144: .getContext(SUBJECT_CONTEXT_KEY);
145: validateRoles(info, subject);
146: } catch (PolicyContextException e) {
147: throw new EJBException(e);
148: }
149:
150: RunAsServiceRemote bean = getBean();
151: bean.userMethod(info);
152: }
153:
154: public void allAuthMethod(CallerInfo info) throws RemoteException {
155: Principal caller = context.getCallerPrincipal();
156: if (caller.equals(info.getCallerIdentity()) == false)
157: throw new EJBException("getCallerPrincipal(" + caller
158: + ") does not equal CallerIdentity: "
159: + info.getCallerIdentity());
160:
161: validateRoles(info);
162: try {
163: Subject subject = (Subject) PolicyContext
164: .getContext(SUBJECT_CONTEXT_KEY);
165: validateRoles(info, subject);
166: } catch (PolicyContextException e) {
167: throw new EJBException(e);
168: }
169:
170: RunAsServiceRemote bean = getBean();
171: bean.allAuthMethod(info);
172: }
173:
174: public void publicMethod(CallerInfo info) throws RemoteException {
175: Principal caller = context.getCallerPrincipal();
176: if (caller.equals(info.getCallerIdentity()) == false)
177: throw new EJBException("getCallerPrincipal(" + caller
178: + ") does not equal CallerIdentity: "
179: + info.getCallerIdentity());
180:
181: validateRoles(info);
182: try {
183: Subject subject = (Subject) PolicyContext
184: .getContext(SUBJECT_CONTEXT_KEY);
185: validateRoles(info, subject);
186: } catch (PolicyContextException e) {
187: throw new EJBException(e);
188: }
189:
190: RunAsServiceRemote bean = getBean();
191: bean.publicMethod(info);
192: }
193:
194: private RunAsServiceRemote getBean() {
195: RunAsServiceRemote bean = null;
196: try {
197: InitialContext ctx = new InitialContext();
198: RunAsServiceRemoteHome home = (RunAsServiceRemoteHome) ctx
199: .lookup("jacc/RunAs");
200: bean = home.create();
201: } catch (Exception e) {
202: throw new EJBException(
203: "Failed to create RunAsServiceRemote", e);
204: }
205: return bean;
206: }
207:
208: private void validateRoles(CallerInfo info) throws EJBException {
209: Iterator iter = info.getExpectedCallerRoles().iterator();
210: StringBuffer buffer = new StringBuffer();
211: while (iter.hasNext()) {
212: String role = (String) iter.next();
213: if (context.isCallerInRole(role) == false) {
214: buffer.append(',');
215: buffer.append(role);
216: }
217: }
218:
219: if (buffer.length() > 0) {
220: buffer.insert(0, "isCallerInRole failed for: ");
221: throw new EJBException(buffer.toString());
222: }
223: }
224:
225: private void validateRoles(CallerInfo info, Subject subject)
226: throws EJBException {
227: // If there are no expected roles succeed
228: if (info.getExpectedCallerRoles().size() == 0)
229: return;
230:
231: Iterator iter = info.getExpectedCallerRoles().iterator();
232: Set groups = subject.getPrincipals(Group.class);
233: if (groups == null || groups.size() == 0)
234: throw new EJBException("No groups found in the subject: "
235: + subject);
236:
237: Group roles = (Group) groups.iterator().next();
238: StringBuffer buffer = new StringBuffer();
239: while (iter.hasNext()) {
240: String role = (String) iter.next();
241: SimplePrincipal srole = new SimplePrincipal(role);
242: if (roles.isMember(srole) == false) {
243: buffer.append(',');
244: buffer.append(role);
245: }
246: }
247:
248: if (buffer.length() > 0) {
249: buffer.insert(0, "Principals failed for: ");
250: throw new EJBException(buffer.toString());
251: }
252: }
253: }
|