1 22 package org.jboss.mq.security; 23 24 import java.security.Principal ; 25 import java.security.acl.Group ; 26 import java.util.Enumeration ; 27 import java.util.HashMap ; 28 import java.util.Iterator ; 29 import java.util.Set ; 30 31 import javax.jms.JMSException ; 32 import javax.jms.JMSSecurityException ; 33 import javax.management.MBeanServer ; 34 import javax.management.MalformedObjectNameException ; 35 import javax.management.ObjectName ; 36 import javax.naming.Context ; 37 import javax.naming.InitialContext ; 38 import javax.naming.NamingException ; 39 import javax.security.auth.Subject ; 40 41 import org.jboss.mq.ConnectionToken; 42 import org.jboss.mq.server.JMSServerInterceptor; 43 import org.jboss.mq.server.jmx.InterceptorMBeanSupport; 44 import org.jboss.security.SimplePrincipal; 45 import org.jboss.security.SubjectSecurityManager; 46 import org.w3c.dom.Element ; 47 48 55 public class SecurityManager extends InterceptorMBeanSupport implements SecurityManagerMBean 56 { 57 60 class SubjectInfo 61 { 62 Subject subject; 63 Principal principal; 64 Group roles; 65 66 public String toString() 67 { 68 return "SubjectInfo {subject=" + subject + ";principal=" + principal + ";roles=" + roles.toString(); 69 } 70 } 71 72 private ObjectName name; 73 Context securityCtx; 74 HashMap authCache = new HashMap (32); 75 HashMap securityConf = new HashMap (32); 76 ServerSecurityInterceptor interceptor; 77 SubjectSecurityManager sec; 78 SessionIDGenerator idGenerator; 79 Element defaultSecurityConfig; 80 String securityDomain; 81 82 protected ObjectName getObjectName(MBeanServer server, ObjectName name) throws MalformedObjectNameException 83 { 84 85 this.name = name == null ? OBJECT_NAME : name; 86 87 return this.name; 88 } 89 90 public JMSServerInterceptor getInvoker() 91 { 92 return interceptor; 93 } 94 95 public Element getDefaultSecurityConfig() 96 { 97 return defaultSecurityConfig; 98 } 99 100 public void setDefaultSecurityConfig(Element conf) throws Exception 101 { 102 defaultSecurityConfig = conf; 103 new SecurityMetadata(conf); 105 } 106 107 public String getSecurityDomain() 108 { 109 return securityDomain; 110 } 111 112 public void setSecurityDomain(String securityDomain) 113 { 114 this.securityDomain = securityDomain; 115 } 116 117 public String printAuthCache() 119 { 120 return authCache.toString(); 121 } 122 123 public void addDestination(String destName, Element conf) throws Exception 124 { 125 SecurityMetadata m = new SecurityMetadata(conf); 126 securityConf.put(destName, m); 127 } 128 129 public void addDestination(String destName, String conf) throws Exception 130 { 131 SecurityMetadata m = new SecurityMetadata(conf); 132 securityConf.put(destName, m); 133 } 134 135 public void removeDestination(String destName) throws Exception 136 { 137 securityConf.remove(destName); 138 } 139 140 public SecurityMetadata getSecurityMetadata(String destName) 141 { 142 SecurityMetadata m = (SecurityMetadata) securityConf.get(destName); 143 if (m == null) 144 { 145 if (defaultSecurityConfig != null) 148 { 149 log.debug("No SecurityMetadadata was available for " + destName + " using default security config"); 150 try 151 { 152 m = new SecurityMetadata(defaultSecurityConfig); 153 } 154 catch (Exception e) 155 { 156 log.warn("Unable to apply default security for destName, using guest " + destName, e); 157 m = new SecurityMetadata(); 158 } 159 } 160 else 161 { 162 log.warn("No SecurityMetadadata was available for " + destName + " adding guest"); 164 m = new SecurityMetadata(); 165 } 166 securityConf.put(destName, m); 167 } 168 return m; 169 } 170 171 public void startService() throws Exception 172 { 173 InitialContext iniCtx = new InitialContext (); 175 try 176 { 177 sec = (SubjectSecurityManager) iniCtx.lookup(securityDomain); 178 } 179 catch (NamingException e) 180 { 181 log.debug("Failed to lookup securityDomain=" + securityDomain, e); 183 if (securityDomain.startsWith("java:/jaas/") == false) 184 sec = (SubjectSecurityManager) iniCtx.lookup("java:/jaas/" + securityDomain); 185 else 186 throw e; 187 } 188 interceptor = new ServerSecurityInterceptor(this); 189 190 idGenerator = new SessionIDGenerator(); 191 192 super.startService(); 193 } 194 195 public void stopService() throws Exception 196 { 197 } 199 200 public String authenticate(String user, String password) throws JMSException 201 { 202 209 boolean trace = log.isTraceEnabled(); 210 SimplePrincipal principal = new SimplePrincipal(user); 211 char[] passwordChars = null; 212 if (password != null) 213 passwordChars = password.toCharArray(); 214 Subject subject = new Subject (); 215 if (sec.isValid(principal, passwordChars, subject)) 216 { 217 if (trace) 218 log.trace("Username: " + user + " is authenticated"); 219 220 String sessionId = generateId(subject); 221 addId(sessionId, subject, principal); 222 223 return sessionId; 225 } 226 else 227 { 228 if (trace) 229 log.trace("User: " + user + " is NOT authenticated"); 230 throw new JMSSecurityException ("User: " + user + " is NOT authenticated"); 231 } 232 } 233 234 public boolean authorize(ConnectionToken token, Set rolePrincipals) throws JMSException 235 { 236 boolean trace = log.isTraceEnabled(); 241 boolean hasRole = false; 242 243 SubjectInfo info = (SubjectInfo) authCache.get(token.getSessionId()); 244 if (info == null) 245 throw new JMSSecurityException ("User session is not valid"); 246 247 if (trace) 248 log.trace( 249 "Checking authorize on subjectInfo: " 250 + info.toString() 251 + " for rolePrincipals " 252 + rolePrincipals.toString()); 253 254 Group group = info.roles; 255 if (group != null) 256 { 257 Iterator iter = rolePrincipals.iterator(); 258 while (hasRole == false && iter.hasNext()) 259 { 260 Principal role = (Principal ) iter.next(); 261 hasRole = group.isMember(role); 262 } 263 264 } 265 return hasRole; 266 } 267 268 public void logout(ConnectionToken token) 270 { 271 if (token == null) 272 return; 273 removeId(token.getSessionId()); 276 } 277 278 private void addId(String id, Subject subject, Principal callerPrincipal) 279 { 280 boolean trace = log.isTraceEnabled(); 281 282 SubjectInfo info = new SubjectInfo(); 283 info.subject = subject; 284 info.principal = callerPrincipal; 285 286 Set subjectGroups = subject.getPrincipals(Group .class); 287 Iterator iter = subjectGroups.iterator(); 288 while (iter.hasNext()) 289 { 290 Group grp = (Group ) iter.next(); 291 String name = grp.getName(); 292 if (name.equals("CallerPrincipal")) 293 { 294 Enumeration members = grp.members(); 295 if (members.hasMoreElements()) 296 info.principal = (Principal ) members.nextElement(); 297 } 298 else if (name.equals("Roles")) 299 { 300 if (trace) 301 log.trace("Adding group : " + grp.getClass() + " " + grp.toString()); 302 info.roles = grp; 303 } 304 } 305 310 if (callerPrincipal == null && info.principal == null) 311 { 312 Set subjectPrincipals = subject.getPrincipals(Principal .class); 313 iter = subjectPrincipals.iterator(); 314 while (iter.hasNext()) 315 { 316 Principal p = (Principal ) iter.next(); 317 if ((p instanceof Group ) == false) 318 info.principal = p; 319 } 320 } 321 322 synchronized (authCache) 323 { 324 authCache.put(id, info); 325 } 326 } 327 328 private void removeId(String id) 329 { 330 synchronized (authCache) 331 { 332 authCache.remove(id); 333 } 334 } 335 336 private String generateId(Subject subject) throws JMSException 337 { 338 try 339 { 340 return idGenerator.nextSessionId(); 341 } 342 catch (Exception ex) 343 { 344 log.error("Could not generate a secure sessionID", ex); 345 throw new JMSSecurityException ("Could not generate a secure sessionID"); 347 } 348 } 349 350 353 public JMSServerInterceptor getInterceptor() 354 { 355 return interceptor; 356 } 357 358 } | Popular Tags |