1 22 package org.jboss.test.security.servlets; 23 24 import java.io.IOException ; 25 import java.security.Principal ; 26 import java.util.HashMap ; 27 import java.util.Iterator ; 28 import java.util.Map ; 29 import java.util.Set ; 30 31 import javax.management.JMException ; 32 import javax.management.MBeanServer ; 33 import javax.management.ObjectName ; 34 import javax.naming.InitialContext ; 35 import javax.security.auth.Subject ; 36 import javax.security.auth.callback.CallbackHandler ; 37 import javax.security.auth.login.LoginException ; 38 import javax.security.auth.spi.LoginModule ; 39 import javax.security.jacc.PolicyContext ; 40 import javax.servlet.ServletException ; 41 import javax.servlet.http.HttpServlet ; 42 import javax.servlet.http.HttpServletRequest ; 43 import javax.servlet.http.HttpServletResponse ; 44 45 import org.jboss.mx.util.MBeanServerLocator; 46 import org.jboss.security.SimpleGroup; 47 import org.jboss.security.SimplePrincipal; 48 import org.jboss.security.SubjectSecurityManager; 49 50 52 59 public class DeepCopySubjectServlet extends HttpServlet 60 { 61 62 private static final long serialVersionUID = -277574499645473218L; 63 64 private Principal anilPrincipal = TestPrincipal.getInstance(); 65 private Principal scottPrincipal = new SimplePrincipal("scott"); 66 67 protected void service(HttpServletRequest request, 68 HttpServletResponse response) 69 throws ServletException , IOException 70 { 71 boolean hashCodeShouldMatch = false; 73 int hashCodeOfAnilPrincipal = System.identityHashCode(anilPrincipal); 74 75 InitialContext context; 76 try 77 { 78 String param = request.getParameter("shouldMatch"); 79 log("param="+param); 80 if(param == null || param.length() == 0) 81 param = "true"; 82 hashCodeShouldMatch = param.equals("true"); 83 84 log("hashCodeShouldMatch="+hashCodeShouldMatch); 85 flushAuthenticationCache("deepcopy", anilPrincipal); 87 context = new InitialContext (); 88 SubjectSecurityManager manager = (SubjectSecurityManager)context.lookup("java:comp/env/security/securityMgr"); 89 Subject testSubject = new Subject (); 90 log("isValid="+manager.isValid(scottPrincipal,"echoman", testSubject)); 92 Subject authSubject = this.getAuthenticatedSubject(manager); 93 log("AuthenticatedSubject["+authSubject+"]"); 94 log("CopiedSubject["+testSubject+"]"); 95 flushAuthenticationCache("deepcopy", anilPrincipal); 97 authSubject = this.getAuthenticatedSubject(manager); 98 log("AuthenticatedSubject after flush["+authSubject+"]"); 99 log("CopiedSubject after flush["+testSubject+"]"); 100 validateSubject(testSubject, hashCodeShouldMatch, hashCodeOfAnilPrincipal); 101 } 102 catch (Exception e) 103 { 104 throw new ServletException (e); 105 } 106 } 107 108 private Subject getAuthenticatedSubject(SubjectSecurityManager mgr) 109 throws Exception 110 { 111 String SUBJECT_CONTEXT_KEY = "javax.security.auth.Subject.container"; 113 Subject subject = (Subject ) PolicyContext.getContext(SUBJECT_CONTEXT_KEY); 114 115 if(subject == null && mgr != null) 117 { 118 subject = mgr.getActiveSubject(); 119 } 120 return subject; 121 } 122 123 133 private void validateSubject(Subject ts, boolean hashCodeShouldMatch, 134 int hashCodeValueToCheck) 135 { 136 boolean anilFound = false; 137 138 Set principalSet = ts.getPrincipals(); 139 if(principalSet == null || principalSet.isEmpty()) 140 throw new RuntimeException ("Principal Set is null"); 141 Iterator iter = principalSet.iterator(); 142 while(iter.hasNext()) 143 { 144 Principal p = (Principal )iter.next(); 145 if(p instanceof TestPrincipal) 146 { 147 verifyTestPrincipal(p,hashCodeShouldMatch,hashCodeValueToCheck); 148 anilFound = true; 149 } 150 } 151 if(!anilFound) 152 throw new RuntimeException ("Test Principal not found"); 153 } 154 155 163 private void verifyTestPrincipal(Principal p, boolean hashCodeShouldMatch, 164 int hashCodeValueToCheck) 165 { 166 TestPrincipal tp = (TestPrincipal)p; 167 int newHashCode = System.identityHashCode(tp); 168 log("[hashCodeShouldMatch="+hashCodeShouldMatch+"::hashCodeValueToCheck="+ hashCodeValueToCheck 169 + "::HashCode of TestPrincipal from copied subject="+ newHashCode+"]"); 170 if(hashCodeShouldMatch) 171 { 172 if(hashCodeValueToCheck != newHashCode) 173 throw new RuntimeException ("HashCodes of the TestPrincipal do not match"); 174 }else 175 { 176 if(hashCodeValueToCheck == newHashCode) 177 throw new RuntimeException ("HashCodes of the TestPrincipal are matching"); 178 } 179 Map map = tp.getMap(); 180 if(map == null || map.isEmpty()) 181 throw new RuntimeException ("Map is null"); 182 String value = (String )map.get("testKey"); 183 if(value == null) 184 throw new RuntimeException ("Value is null"); 185 if(!value.equals("testValue")) 186 throw new RuntimeException ("Value is not equal to testValue"); 187 } 188 189 196 private void flushAuthenticationCache(String domain, Principal principal) throws JMException 197 { 198 MBeanServer server = MBeanServerLocator.locateJBoss(); 199 ObjectName on = new ObjectName ("jboss.security:service=JaasSecurityManager"); 200 Object [] obj = new Object [] {domain, principal}; 201 String [] sig = new String []{"java.lang.String", "java.security.Principal"}; 202 203 server.invoke(on,"flushAuthenticationCache", obj, sig); 205 } 206 207 215 public static class TestLoginModule implements LoginModule 216 { 217 public TestLoginModule() 218 { 219 super(); 220 } 221 222 public void initialize(Subject subject, CallbackHandler callbackHandler, 223 Map sharedState, Map options) 224 { 225 TestPrincipal tp = TestPrincipal.getInstance(); 226 if(subject != null) 227 { 228 subject.getPrincipals().add(tp); 229 } 230 231 SimpleGroup sg = new SimpleGroup("Roles"); 232 sg.addMember(new SimplePrincipal("Echo")); 233 subject.getPrincipals().add(sg); 234 SimpleGroup cg = new SimpleGroup("CallerPrincipal"); 235 cg.addMember(tp); 236 subject.getPrincipals().add(cg); 237 } 238 239 public boolean login() throws LoginException 240 { 241 return true; 242 } 243 244 public boolean commit() throws LoginException 245 { 246 return true; 247 } 248 249 public boolean abort() throws LoginException 250 { 251 return true; 252 } 253 254 public boolean logout() throws LoginException 255 { 256 return true; 257 } 258 } 259 260 267 public static class TestPrincipal extends SimplePrincipal implements Cloneable 268 { 269 270 private static final long serialVersionUID = -6160570085301760185L; 271 272 private HashMap map = new HashMap (); 273 274 private static TestPrincipal _instance = new TestPrincipal("anil"); 275 276 public static TestPrincipal getInstance() 277 { 278 return _instance; 279 } 280 281 public TestPrincipal(String name) 282 { 283 super(name); 284 map.put("testKey","testValue"); 285 } 286 287 public Map getMap() 288 { 289 return map; 290 } 291 292 public Object clone() throws CloneNotSupportedException 293 { 294 TestPrincipal tp = (TestPrincipal)super.clone(); 295 tp.map = (HashMap )this.map.clone(); 296 return tp; 297 } 298 299 public boolean equals(Object another) 300 { 301 return super.equals(another); 302 } 303 304 public String toString() 305 { 306 return this.getName(); 307 } 308 } 309 } 310 | Popular Tags |