/* * JBoss, Home of Professional Open Source. * Copyright 2008, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.test.security.ejb; import java.util.Set; import java.util.Iterator; import java.security.GeneralSecurityException; import java.security.Principal; import java.security.acl.Group; import javax.security.auth.Subject; import javax.security.jacc.PolicyContext; import javax.security.jacc.PolicyContextException; import javax.ejb.SessionContext; import javax.ejb.SessionBean; import javax.ejb.FinderException; import javax.naming.InitialContext; import org.jboss.security.SecurityAssociation; import org.jboss.test.security.interfaces.StatelessSessionHome; import org.jboss.test.security.interfaces.StatelessSession; import org.jboss.test.security.interfaces.StatefulSessionHome; import org.jboss.test.security.interfaces.EntityHome; import org.jboss.test.security.interfaces.Entity; import org.jboss.test.security.interfaces.StatefulSession; /** * A session facade that tests that the security context reflected by the * SecurityAssociation.getSubject and PolicyContext. This will not run under * the security manager tests as ejbs are not granted access to these security * apis. * * @author Scott.Stark@jboss.org * @version $Revision: 81036 $ */ public class SubjectSessionBean implements SessionBean { /** The JACC PolicyContext key for the current Subject */ private static final String SUBJECT_CONTEXT_KEY = "javax.security.auth.Subject.container"; private SessionContext context; public void ejbCreate() { } public void ejbActivate() { } public void ejbPassivate() { } public void ejbRemove() { } public void setSessionContext(SessionContext context) { this.context = context; } /** * * @param callerName * @param callerPrincipals * @throws GeneralSecurityException */ public void validateCallerContext(String callerName, Set callerPrincipals) throws GeneralSecurityException { Principal caller = context.getCallerPrincipal(); String name = caller.getName(); if( name.equals(callerName) == false ) throw new GeneralSecurityException("CallerPrincipal.name("+name+") != "+callerName); validatePolicyContextSubject("enter", callerPrincipals); validateSecurityAssociationSubject("enter", callerPrincipals); InitialContext ctx = null; try { ctx = new InitialContext(); StatelessSessionHome home = (StatelessSessionHome) ctx.lookup("java:comp/env/ejb/StatelessSession"); StatelessSession bean = home.create(); bean.echo("validateCallerContext"); validatePolicyContextSubject("post stateless", callerPrincipals); validateSecurityAssociationSubject("post stateless", callerPrincipals); StatefulSessionHome home2 = (StatefulSessionHome) ctx.lookup("java:comp/env/ejb/StatefulSession"); StatefulSession bean2 = home2.create("validateCallerContext"); bean2.echo("validateCallerContext"); validatePolicyContextSubject("post stateful", callerPrincipals); validateSecurityAssociationSubject("post stateful", callerPrincipals); EntityHome home3 = (EntityHome) ctx.lookup("java:comp/env/ejb/Entity"); Entity bean3 = null; try { bean3 = home3.findByPrimaryKey("validateCallerContext"); } catch(FinderException e) { bean3 = home3.create("validateCallerContext"); } bean3.echo("validateCallerContext"); } catch(Exception e) { GeneralSecurityException ex = new GeneralSecurityException("Unexpected exception"); ex.initCause(e); throw ex; } validatePolicyContextSubject("exit", callerPrincipals); validateSecurityAssociationSubject("exit", callerPrincipals); } /** * Get the active subject as seen by the JACC policy context handler. * @throws GeneralSecurityException */ protected void validatePolicyContextSubject(String ctx, Set callerPrincipals) throws GeneralSecurityException { try { Subject caller = caller = (Subject) PolicyContext.getContext(SUBJECT_CONTEXT_KEY); if( contains(caller, callerPrincipals) == false ) { String msg = ctx+", PolicyContext subject: "+caller +" does not contain expected principals: "+callerPrincipals; throw new GeneralSecurityException(msg); } } catch(PolicyContextException e) { } } /** * Get the active subject as seen by the jboss SecurityAssociation * @throws GeneralSecurityException */ protected void validateSecurityAssociationSubject(String ctx, Set callerPrincipals) throws GeneralSecurityException { Subject caller = SecurityAssociation.getSubject(); if( contains(caller, callerPrincipals) == false ) { String msg = ctx+", SecurityAssociation subject: "+caller +" does not contain expected principals: "+callerPrincipals; throw new GeneralSecurityException(msg); } } protected boolean contains(Subject s, Set callerPrincipals) { Set gs = s.getPrincipals(Group.class); Iterator iter = gs.iterator(); while( iter.hasNext() ) { Group g = (Group) iter.next(); if( g.getName().equals("Roles") ) { Iterator citer = callerPrincipals.iterator(); while( citer.hasNext() ) { Principal p = (Principal) citer.next(); if( g.isMember(p) == false ) return false; } } } return true; } }