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.util.Set;
025: import java.util.Iterator;
026: import java.security.GeneralSecurityException;
027: import java.security.Principal;
028: import java.security.acl.Group;
029: import javax.security.auth.Subject;
030: import javax.security.jacc.PolicyContext;
031: import javax.security.jacc.PolicyContextException;
032: import javax.ejb.SessionContext;
033: import javax.ejb.SessionBean;
034: import javax.ejb.FinderException;
035: import javax.naming.InitialContext;
036:
037: import org.jboss.security.SecurityAssociation;
038: import org.jboss.test.security.interfaces.StatelessSessionHome;
039: import org.jboss.test.security.interfaces.StatelessSession;
040: import org.jboss.test.security.interfaces.StatefulSessionHome;
041: import org.jboss.test.security.interfaces.EntityHome;
042: import org.jboss.test.security.interfaces.Entity;
043: import org.jboss.test.security.interfaces.StatefulSession;
044:
045: /**
046: * A session facade that tests that the security context reflected by the
047: * SecurityAssociation.getSubject and PolicyContext. This will not run under
048: * the security manager tests as ejbs are not granted access to these security
049: * apis.
050: *
051: * @author Scott.Stark@jboss.org
052: * @version $Revision: 57211 $
053: */
054: public class SubjectSessionBean implements SessionBean {
055: /** The JACC PolicyContext key for the current Subject */
056: private static final String SUBJECT_CONTEXT_KEY = "javax.security.auth.Subject.container";
057:
058: private SessionContext context;
059:
060: public void ejbCreate() {
061: }
062:
063: public void ejbActivate() {
064: }
065:
066: public void ejbPassivate() {
067: }
068:
069: public void ejbRemove() {
070: }
071:
072: public void setSessionContext(SessionContext context) {
073: this .context = context;
074: }
075:
076: /**
077: *
078: * @param callerName
079: * @param callerPrincipals
080: * @throws GeneralSecurityException
081: */
082: public void validateCallerContext(String callerName,
083: Set callerPrincipals) throws GeneralSecurityException {
084: Principal caller = context.getCallerPrincipal();
085: String name = caller.getName();
086: if (name.equals(callerName) == false)
087: throw new GeneralSecurityException("CallerPrincipal.name("
088: + name + ") != " + callerName);
089:
090: validatePolicyContextSubject("enter", callerPrincipals);
091: validateSecurityAssociationSubject("enter", callerPrincipals);
092:
093: InitialContext ctx = null;
094: try {
095: ctx = new InitialContext();
096: StatelessSessionHome home = (StatelessSessionHome) ctx
097: .lookup("java:comp/env/ejb/StatelessSession");
098: StatelessSession bean = home.create();
099: bean.echo("validateCallerContext");
100: validatePolicyContextSubject("post stateless",
101: callerPrincipals);
102: validateSecurityAssociationSubject("post stateless",
103: callerPrincipals);
104:
105: StatefulSessionHome home2 = (StatefulSessionHome) ctx
106: .lookup("java:comp/env/ejb/StatefulSession");
107: StatefulSession bean2 = home2
108: .create("validateCallerContext");
109: bean2.echo("validateCallerContext");
110: validatePolicyContextSubject("post stateful",
111: callerPrincipals);
112: validateSecurityAssociationSubject("post stateful",
113: callerPrincipals);
114:
115: EntityHome home3 = (EntityHome) ctx
116: .lookup("java:comp/env/ejb/Entity");
117: Entity bean3 = null;
118: try {
119: bean3 = home3.findByPrimaryKey("validateCallerContext");
120: } catch (FinderException e) {
121: bean3 = home3.create("validateCallerContext");
122: }
123: bean3.echo("validateCallerContext");
124: } catch (Exception e) {
125: GeneralSecurityException ex = new GeneralSecurityException(
126: "Unexpected exception");
127: ex.initCause(e);
128: throw ex;
129: }
130: validatePolicyContextSubject("exit", callerPrincipals);
131: validateSecurityAssociationSubject("exit", callerPrincipals);
132: }
133:
134: /**
135: * Get the active subject as seen by the JACC policy context handler.
136: * @throws GeneralSecurityException
137: */
138: protected void validatePolicyContextSubject(String ctx,
139: Set callerPrincipals) throws GeneralSecurityException {
140: try {
141: Subject caller = caller = (Subject) PolicyContext
142: .getContext(SUBJECT_CONTEXT_KEY);
143: if (contains(caller, callerPrincipals) == false) {
144: String msg = ctx + ", PolicyContext subject: " + caller
145: + " does not contain expected principals: "
146: + callerPrincipals;
147: throw new GeneralSecurityException(msg);
148: }
149: } catch (PolicyContextException e) {
150:
151: }
152: }
153:
154: /**
155: * Get the active subject as seen by the jboss SecurityAssociation
156: * @throws GeneralSecurityException
157: */
158: protected void validateSecurityAssociationSubject(String ctx,
159: Set callerPrincipals) throws GeneralSecurityException {
160: Subject caller = SecurityAssociation.getSubject();
161: if (contains(caller, callerPrincipals) == false) {
162: String msg = ctx + ", SecurityAssociation subject: "
163: + caller
164: + " does not contain expected principals: "
165: + callerPrincipals;
166: throw new GeneralSecurityException(msg);
167: }
168: }
169:
170: protected boolean contains(Subject s, Set callerPrincipals) {
171: Set gs = s.getPrincipals(Group.class);
172: Iterator iter = gs.iterator();
173: while (iter.hasNext()) {
174: Group g = (Group) iter.next();
175: if (g.getName().equals("Roles")) {
176: Iterator citer = callerPrincipals.iterator();
177: while (citer.hasNext()) {
178: Principal p = (Principal) citer.next();
179: if (g.isMember(p) == false)
180: return false;
181: }
182: }
183: }
184: return true;
185: }
186: }
|