1 17 package org.apache.geronimo.security.jaas.client; 18 19 import java.util.HashMap ; 20 import java.util.Map ; 21 import java.util.Set ; 22 import javax.management.MalformedObjectNameException ; 23 import javax.management.ObjectName ; 24 import javax.security.auth.Subject ; 25 import javax.security.auth.callback.CallbackHandler ; 26 import javax.security.auth.login.FailedLoginException ; 27 import javax.security.auth.login.LoginException ; 28 import javax.security.auth.spi.LoginModule ; 29 30 import org.apache.geronimo.kernel.Kernel; 31 import org.apache.geronimo.kernel.KernelRegistry; 32 import org.apache.geronimo.kernel.GBeanNotFoundException; 33 import org.apache.geronimo.security.jaas.server.JaasSessionId; 34 import org.apache.geronimo.security.jaas.server.JaasLoginModuleConfiguration; 35 import org.apache.geronimo.security.jaas.LoginModuleControlFlag; 36 import org.apache.geronimo.security.jaas.LoginUtils; 37 import org.apache.geronimo.security.jaas.server.JaasLoginServiceMBean; 38 import org.apache.geronimo.security.remoting.jmx.JaasLoginServiceRemotingClient; 39 40 41 54 public class JaasLoginCoordinator implements LoginModule { 55 public final static String OPTION_HOST = "host"; 56 public final static String OPTION_PORT = "port"; 57 public final static String OPTION_KERNEL = "kernel"; 58 public final static String OPTION_REALM = "realm"; 59 public final static String OPTION_SERVICENAME = "serviceName"; 60 public final static String OPTION_SERVICE_INSTANCE = "serviceInstance"; 61 private String serverHost; 62 private int serverPort; 63 private String realmName; 64 private String kernelName; 65 private ObjectName serviceName; 66 private JaasLoginServiceMBean service; 67 private CallbackHandler handler; 68 private Subject subject; 69 private JaasSessionId sessionHandle; 70 private LoginModuleProxy[] proxies; 71 private final Map sharedState = new HashMap (); 72 73 74 public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { 75 serverHost = (String ) options.get(OPTION_HOST); 76 Object port = options.get(OPTION_PORT); 77 if (port != null) { 78 serverPort = Integer.parseInt((String ) port); 79 } 80 realmName = (String ) options.get(OPTION_REALM); 81 kernelName = (String ) options.get(OPTION_KERNEL); 82 try { 83 String s = (String ) options.get(OPTION_SERVICENAME); 84 serviceName = s != null ? new ObjectName (s) : null; 85 } catch (MalformedObjectNameException e) { 86 throw new IllegalArgumentException ("option " + OPTION_SERVICENAME + "is not a valid ObjectName: " + options.get(OPTION_SERVICENAME)); 87 } 88 if (port != null || kernelName != null) { 89 service = connect(); 90 } else { 91 service = (JaasLoginServiceMBean) options.get(OPTION_SERVICE_INSTANCE); 93 } 94 handler = callbackHandler; 95 if (subject == null) { 96 this.subject = new Subject (); 97 } else { 98 this.subject = subject; 99 } 100 } 101 102 public boolean login() throws LoginException { 103 sessionHandle = service.connectToRealm(realmName); 104 JaasLoginModuleConfiguration[] config = service.getLoginConfiguration(sessionHandle); 105 proxies = new LoginModuleProxy[config.length]; 106 107 for (int i = 0; i < proxies.length; i++) { 108 if (config[i].isServerSide()) { 109 proxies[i] = new ServerLoginProxy(config[i].getFlag(), subject, i, service, sessionHandle); 110 } else { 111 LoginModule source = config[i].getLoginModule(JaasLoginCoordinator.class.getClassLoader()); 112 if (config[i].isWrapPrincipals()) { 113 proxies[i] = new WrappingClientLoginModuleProxy(config[i].getFlag(), subject, source, config[i].getLoginDomainName(), realmName); 114 } else { 115 proxies[i] = new ClientLoginModuleProxy(config[i].getFlag(), subject, source); 116 } 117 } 118 proxies[i].initialize(subject, handler, sharedState, config[i].getOptions()); 119 syncSharedState(); 120 } 121 boolean result = performLogin(); 122 if(result) { 123 return true; 124 } else { 125 throw new FailedLoginException (); 127 } 128 } 129 130 public boolean commit() throws LoginException { 131 for (int i = 0; i < proxies.length; i++) { 132 proxies[i].commit(); 133 syncSharedState(); 134 syncPrincipals(); 135 } 136 subject.getPrincipals().add(service.loginSucceeded(sessionHandle)); 137 return true; 138 } 139 140 public boolean abort() throws LoginException { 141 try { 142 for (int i = 0; i < proxies.length; i++) { 143 proxies[i].abort(); 144 syncSharedState(); 145 } 146 } finally { 147 service.loginFailed(sessionHandle); 148 } 149 clear(); 150 return true; 151 } 152 153 public boolean logout() throws LoginException { 154 try { 155 for (int i = 0; i < proxies.length; i++) { 156 proxies[i].logout(); 157 syncSharedState(); 158 } 159 } finally { 160 service.logout(sessionHandle); 161 } 162 clear(); 163 return true; 164 } 165 166 private void clear() { 167 service = null; 168 serverHost = null; 169 serverPort = 0; 170 realmName = null; 171 kernelName = null; 172 service = null; 173 handler = null; 174 subject = null; 175 sessionHandle = null; 176 proxies = null; 177 } 178 179 private JaasLoginServiceMBean connect() { 180 if (serverHost != null && serverPort > 0) { 181 return JaasLoginServiceRemotingClient.create(serverHost, serverPort); 182 } else { 183 Kernel kernel = KernelRegistry.getKernel(kernelName); 184 try { 185 return (JaasLoginServiceMBean) kernel.getGBean(serviceName); 186 } catch (GBeanNotFoundException e) { 187 IllegalStateException illegalStateException = new IllegalStateException (); 188 illegalStateException.initCause(e); 189 throw illegalStateException; 190 } 191 } 192 } 193 194 200 private boolean performLogin() throws LoginException { 201 Boolean success = null; 202 Boolean backup = null; 203 204 for (int i = 0; i < proxies.length; i++) { 205 LoginModuleProxy proxy = proxies[i]; 206 boolean result; 207 try { 208 result = proxy.login(); 209 } catch(LoginException e) { 210 result = false; } 212 syncSharedState(); 213 214 if (proxy.getControlFlag() == LoginModuleControlFlag.REQUIRED) { 215 if (success == null || success.booleanValue()) { 216 success = result ? Boolean.TRUE : Boolean.FALSE; 217 } 218 } else if (proxy.getControlFlag() == LoginModuleControlFlag.REQUISITE) { 219 if (!result) { 220 return false; 221 } else if (success == null) { 222 success = Boolean.TRUE; 223 } 224 } else if (proxy.getControlFlag() == LoginModuleControlFlag.SUFFICIENT) { 225 if (result && (success == null || success.booleanValue())) { 226 return true; 227 } 228 } else if (proxy.getControlFlag() == LoginModuleControlFlag.OPTIONAL) { 229 if (backup == null || backup.booleanValue()) { 230 backup = result ? Boolean.TRUE : Boolean.FALSE; 231 } 232 } 233 } 234 if (success != null) { 236 return success.booleanValue(); 237 } 238 if (backup != null) { 240 return backup.booleanValue(); 241 } 242 return false; 244 } 245 246 private void syncSharedState() throws LoginException { 247 Map map = service.syncShareState(sessionHandle, LoginUtils.getSerializableCopy(sharedState)); 248 sharedState.putAll(map); 249 } 250 251 private void syncPrincipals() throws LoginException { 252 Set principals = service.syncPrincipals(sessionHandle, subject.getPrincipals()); 253 subject.getPrincipals().addAll(principals); 254 } 255 } 256 | Popular Tags |