1 16 package org.apache.cocoon.webapps.authentication.components; 17 18 import java.io.IOException ; 19 import java.util.HashMap ; 20 import java.util.Iterator ; 21 import java.util.List ; 22 import java.util.Map ; 23 24 import org.apache.avalon.framework.activity.Disposable; 25 import org.apache.avalon.framework.component.Component; 26 import org.apache.avalon.framework.configuration.ConfigurationException; 27 import org.apache.avalon.framework.container.ContainerUtil; 28 import org.apache.avalon.framework.context.Context; 29 import org.apache.avalon.framework.context.ContextException; 30 import org.apache.avalon.framework.context.Contextualizable; 31 import org.apache.avalon.framework.logger.AbstractLogEnabled; 32 import org.apache.avalon.framework.service.ServiceException; 33 import org.apache.avalon.framework.service.ServiceManager; 34 import org.apache.avalon.framework.service.Serviceable; 35 import org.apache.avalon.framework.thread.ThreadSafe; 36 import org.apache.cocoon.ProcessingException; 37 import org.apache.cocoon.components.ContextHelper; 38 import org.apache.cocoon.components.SitemapConfigurable; 39 import org.apache.cocoon.components.SitemapConfigurationHolder; 40 import org.apache.cocoon.environment.Redirector; 41 import org.apache.cocoon.environment.Request; 42 import org.apache.cocoon.environment.Session; 43 import org.apache.cocoon.util.ClassUtils; 44 import org.apache.cocoon.webapps.authentication.AuthenticationConstants; 45 import org.apache.cocoon.webapps.authentication.AuthenticationManager; 46 import org.apache.cocoon.webapps.authentication.configuration.ApplicationConfiguration; 47 import org.apache.cocoon.webapps.authentication.configuration.HandlerConfiguration; 48 import org.apache.cocoon.webapps.authentication.context.AuthenticationContext; 49 import org.apache.cocoon.webapps.authentication.user.RequestState; 50 import org.apache.cocoon.webapps.authentication.user.UserHandler; 51 import org.apache.cocoon.webapps.authentication.user.UserState; 52 import org.apache.cocoon.webapps.session.ContextManager; 53 import org.apache.cocoon.webapps.session.SessionConstants; 54 import org.apache.cocoon.webapps.session.SessionManager; 55 import org.apache.cocoon.webapps.session.context.SessionContext; 56 import org.apache.excalibur.source.SourceParameters; 57 import org.apache.excalibur.source.SourceResolver; 58 import org.apache.excalibur.source.SourceUtil; 59 import org.apache.excalibur.xml.xpath.XPathProcessor; 60 import org.w3c.dom.DocumentFragment ; 61 import org.w3c.dom.Node ; 62 import org.xml.sax.SAXException ; 63 64 70 public class DefaultAuthenticationManager 71 extends AbstractLogEnabled 72 implements AuthenticationManager, 73 SitemapConfigurable, 74 Serviceable, 75 Disposable, 76 ThreadSafe, 77 Contextualizable, 78 Component { 79 80 81 public final static String SESSION_ATTRIBUTE_USER_STATUS = DefaultAuthenticationManager.class.getName() + "/UserStatus"; 82 83 84 protected SitemapConfigurationHolder holder; 85 86 87 protected ServiceManager manager; 88 89 90 protected SourceResolver resolver; 91 92 93 protected Context context; 94 95 96 protected Map authenticators = new HashMap (); 97 98 99 protected XPathProcessor xpathProcessor; 100 101 102 private static final String REQUEST_STATE_KEY = RequestState.class.getName(); 103 104 107 public void configure(SitemapConfigurationHolder holder) 108 throws ConfigurationException { 109 this.holder = holder; 110 } 111 112 115 private Map getHandlerConfigurations() 116 throws ProcessingException { 117 Map configs = (Map ) this.holder.getPreparedConfiguration(); 118 if ( null == configs ) { 119 try { 120 configs = DefaultHandlerManager.prepareHandlerConfiguration(ContextHelper.getObjectModel(this.context), 121 this.holder); 122 } catch (ConfigurationException ce) { 123 throw new ProcessingException("Configuration error.", ce); 124 } 125 } 126 return configs; 127 } 128 129 134 private HandlerConfiguration getHandlerConfiguration(String name) 135 throws ProcessingException { 136 final Map configs = this.getHandlerConfigurations(); 137 HandlerConfiguration c = null; 138 if ( configs != null) { 139 c = (HandlerConfiguration)configs.get( name ); 140 } 141 return c; 142 } 143 144 private Request getRequest() { 145 return ContextHelper.getRequest(this.context); 146 } 147 148 private Session getSession(boolean create) { 149 return this.getRequest().getSession(create); 150 } 151 152 private UserState getUserState() { 153 final Session session = this.getSession( false ); 154 UserState status = null; 155 if ( session != null) { 156 status = (UserState) session.getAttribute(SESSION_ATTRIBUTE_USER_STATUS); 157 } 158 return status; 159 } 160 161 private UserState createUserState() { 162 UserState status = this.getUserState(); 163 if ( status == null ) { 164 final Session session = this.getSession(true); 165 status = new UserState(); 166 session.setAttribute(SESSION_ATTRIBUTE_USER_STATUS, status); 167 } 168 return status; 169 } 170 171 private UserHandler getUserHandler(String name) { 172 final UserState status = this.getUserState(); 173 if ( status != null ) { 174 return status.getHandler( name ); 175 } 176 return null; 177 } 178 179 private void updateUserState() { 180 final Session session = this.getSession(true); 181 Object status = session.getAttribute(SESSION_ATTRIBUTE_USER_STATUS); 182 session.setAttribute(SESSION_ATTRIBUTE_USER_STATUS, status); 183 } 184 185 188 public UserHandler login(String handlerName, 189 String applicationName, 190 SourceParameters parameters) 191 throws ProcessingException { 192 HandlerConfiguration config = this.getHandlerConfiguration( handlerName ); 193 if ( config == null ) { 194 throw new ProcessingException("Unknown handler to authenticate: " + handlerName); 195 } 196 UserHandler handler = this.getUserHandler( handlerName ); 198 if ( handler != null ) { 199 throw new ProcessingException("User is already authenticated using handler: " + handlerName); 200 } 201 202 Authenticator authenticator = this.lookupAuthenticator( config ); 203 try { 204 Authenticator.AuthenticationResult result = authenticator.authenticate( config, parameters ); 205 if (result != null) { 206 if (result.valid) { 207 AuthenticationContext authContext = new AuthenticationContext(this.context, this.xpathProcessor, this.resolver); 208 handler = new UserHandler(config, authContext); 209 authContext.init(result.result); 211 } else { 212 ContextManager contextManager = null; 214 try { 215 contextManager = (ContextManager) this.manager.lookup( ContextManager.ROLE ); 216 SessionContext temp = contextManager.getContext( SessionConstants.TEMPORARY_CONTEXT ); 217 218 final DocumentFragment fragment = result.result.createDocumentFragment(); 219 final Node root = result.result.getDocumentElement(); 220 root.normalize(); 221 Node child; 222 boolean appendedNode = false; 223 while (root.hasChildNodes() ) { 224 child = root.getFirstChild(); 225 root.removeChild(child); 226 if (appendedNode 228 || child.getNodeType() != Node.TEXT_NODE 229 || child.getNodeValue().trim().length() > 0) { 230 fragment.appendChild(child); 231 appendedNode = true; 232 } 233 } 234 temp.appendXML("/", fragment); 235 } catch ( ServiceException se ) { 236 throw new ProcessingException("Unable to lookup session manager.", se); 237 } finally { 238 this.manager.release( contextManager ); 239 } 240 } 241 } 242 } finally { 243 this.releaseAuthenticator( authenticator, config ); 244 } 245 246 if ( handler != null ) { 247 final UserState status = this.createUserState(); 249 250 status.addHandler( handler ); 251 this.updateUserState(); 252 253 RequestState state = new RequestState( handler, applicationName); 255 this.setState( state ); 256 state.initialize( this.resolver ); 257 258 Iterator applications = handler.getHandlerConfiguration().getApplications().values().iterator(); 260 261 while ( applications.hasNext() ) { 262 ApplicationConfiguration appHandler = (ApplicationConfiguration)applications.next(); 263 if ( !appHandler.getLoadOnDemand() ) { 264 handler.getContext().loadApplicationXML( appHandler, this.resolver ); 265 } 266 } 267 } 268 269 return handler; 270 } 271 272 275 protected void releaseAuthenticator(Authenticator authenticator, HandlerConfiguration config) { 276 } 278 279 282 protected Authenticator lookupAuthenticator(HandlerConfiguration config) 283 throws ProcessingException { 284 final String name = config.getAuthenticatorClassName(); 285 Authenticator authenticator = (Authenticator) this.authenticators.get(name); 286 if ( authenticator == null ) { 287 synchronized (this) { 288 authenticator = (Authenticator) this.authenticators.get(name); 289 if ( authenticator == null ) { 290 try { 291 authenticator = (Authenticator) ClassUtils.newInstance(name); 292 ContainerUtil.enableLogging( authenticator, this.getLogger() ); 293 ContainerUtil.contextualize( authenticator, this.context); 294 ContainerUtil.service( authenticator, this.manager ); 295 ContainerUtil.initialize( authenticator ); 296 this.authenticators.put(name, authenticator); 297 298 } catch (Exception e ) { 299 throw new ProcessingException("Unable to initialize authenticator from class " + name, e); 300 } 301 } 302 } 303 } 304 return authenticator; 305 } 306 307 310 public boolean checkAuthentication(Redirector redirector, 311 String handlerName, 312 String applicationName) 313 throws IOException , ProcessingException { 314 HandlerConfiguration config = this.getHandlerConfiguration( handlerName ); 315 if ( config == null ) { 316 throw new ProcessingException("Unknown handler to check: " + handlerName); 317 } 318 UserHandler handler = this.getUserHandler( handlerName ); 320 final boolean authenticated = ( handler != null ); 321 if ( !authenticated ) { 322 if (redirector != null) { 323 SourceParameters parameters = config.getRedirectParameters(); 325 if (parameters == null) parameters = new SourceParameters(); 326 final Request request = this.getRequest(); 327 String resource = request.getRequestURI(); 328 if (request.getQueryString() != null) { 329 resource += '?' + request.getQueryString(); 330 } 331 332 parameters.setSingleParameterValue("resource", resource); 333 final String redirectURI = config.getRedirectURI(); 334 redirector.globalRedirect(false, SourceUtil.appendParameters(redirectURI, parameters)); 335 } 336 } else { 337 RequestState state = new RequestState( handler, applicationName ); 339 this.setState( state ); 340 state.initialize( this.resolver ); 341 } 342 343 return authenticated; 344 } 345 346 public String getForwardingURI(String handlerName) throws ProcessingException { 347 HandlerConfiguration config = this.getHandlerConfiguration( handlerName ); 348 SourceParameters parameters = config.getRedirectParameters(); 349 if (parameters == null) parameters = new SourceParameters(); 350 final Request request = this.getRequest(); 351 String resource = request.getRequestURI(); 352 if (request.getQueryString() != null) { 353 resource += '?' + request.getQueryString(); 354 } 355 356 parameters.setSingleParameterValue("resource", resource); 357 final String redirectURI = config.getRedirectURI(); 358 return SourceUtil.appendParameters(redirectURI, parameters); 359 } 360 361 364 public UserHandler isAuthenticated(String handlerName) 365 throws ProcessingException { 366 return this.getUserHandler( handlerName ); 367 } 368 369 372 public void logout(String handlerName, int mode) 373 throws ProcessingException { 374 HandlerConfiguration config = this.getHandlerConfiguration( handlerName ); 375 if ( config == null ) { 376 throw new ProcessingException("Unknown handler to logout: " + handlerName); 377 } 378 UserHandler handler = this.getUserHandler( handlerName ); 380 if ( handler != null ) { 382 383 411 try { 413 this.lookupAuthenticator(config).logout(handler); 414 } catch (Exception ignore) { 415 } 417 418 List applicationContexts = handler.getApplicationContexts(); 419 if ( applicationContexts != null ) { 420 ContextManager contextManager = null; 421 422 try { 423 contextManager = (ContextManager)this.manager.lookup(ContextManager.ROLE); 424 425 Iterator i = applicationContexts.iterator(); 426 while ( i.hasNext() ) { 427 final String current = (String )i.next(); 428 contextManager.deleteContext( current ); 429 } 430 } catch (ServiceException ce) { 431 throw new ProcessingException("Unable to create session context.", ce); 432 } finally { 433 this.manager.release( contextManager); 434 } 435 } 436 437 UserState status = this.getUserState(); 438 status.removeHandler( handlerName ); 439 this.updateUserState(); 440 441 SessionManager sessionManager = null; 443 try { 444 sessionManager = (SessionManager)this.manager.lookup( SessionManager.ROLE ); 445 446 if ( mode == AuthenticationConstants.LOGOUT_MODE_IMMEDIATELY ) { 447 sessionManager.terminateSession(true); 448 } else if ( mode == AuthenticationConstants.LOGOUT_MODE_IF_UNUSED ) { 449 if ( !status.hasHandler()) { 450 sessionManager.terminateSession( false ); 451 } 452 453 } else if ( mode == AuthenticationConstants.LOGOUT_MODE_IF_NOT_AUTHENTICATED) { 454 if ( !status.hasHandler()) { 455 sessionManager.terminateSession( true ); 456 } 457 } else { 458 throw new ProcessingException("Unknown logout mode: " + mode); 459 } 460 461 } catch (ServiceException se) { 462 throw new ProcessingException("Unable to lookup session manager.", se); 463 } finally { 464 this.manager.release( sessionManager ); 465 } 466 } 467 } 468 469 472 public void service(ServiceManager manager) 473 throws ServiceException { 474 this.manager = manager; 475 this.resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE); 476 this.xpathProcessor = (XPathProcessor)this.manager.lookup(XPathProcessor.ROLE); 477 } 478 479 482 public void dispose() { 483 Iterator iter = this.authenticators.values().iterator(); 484 while ( iter.hasNext() ) { 485 final Authenticator authenticator = (Authenticator) iter.next(); 486 ContainerUtil.dispose( authenticator ); 487 } 488 if ( this.manager != null) { 489 this.manager.release( this.resolver ); 490 this.manager.release(this.xpathProcessor); 491 this.resolver = null; 492 this.xpathProcessor = null; 493 this.manager = null; 494 } 495 } 496 497 500 public RequestState getState() { 501 return getRequestState(this.context); 502 } 503 504 public static RequestState getRequestState(Context context) { 505 final Request req = ContextHelper.getRequest(context); 506 return (RequestState)req.getAttribute( REQUEST_STATE_KEY); 507 } 508 509 512 public void contextualize(Context context) throws ContextException { 513 this.context = context; 514 } 515 516 protected void setState(RequestState status) { 517 final Request req = ContextHelper.getRequest(this.context); 518 if ( status != null ) { 519 req.setAttribute( REQUEST_STATE_KEY, status); 520 } else { 521 req.removeAttribute( REQUEST_STATE_KEY ); 522 } 523 } 524 525 529 public SessionContext createApplicationContext(String name, 530 String loadURI, 531 String saveURI) 532 throws ProcessingException { 533 RequestState state = this.getState(); 534 UserHandler handler = state.getHandler(); 535 536 SessionContext context = null; 537 538 if ( handler != null ) { 539 ContextManager contextManager = null; 540 try { 541 contextManager = (ContextManager)this.manager.lookup(ContextManager.ROLE); 542 context = contextManager.createContext(name, loadURI, saveURI); 544 handler.addApplicationContext( name ); 545 546 } catch (ServiceException ce) { 547 throw new ProcessingException("Unable to create session context.", ce); 548 } catch (IOException ioe) { 549 throw new ProcessingException("Unable to create session context.", ioe); 550 } catch (SAXException saxe) { 551 throw new ProcessingException("Unable to create session context.", saxe); 552 } finally { 553 manager.release( contextManager); 554 } 555 } else { 556 throw new ProcessingException("No handler defined. Unable to create application context."); 557 } 558 559 return context; 560 } 561 } 562 | Popular Tags |