PageRenderTime 27ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/blocks/cocoon-authentication-fw/cocoon-authentication-fw-impl/src/main/java/org/apache/cocoon/webapps/authentication/components/PipelineAuthenticator.java

https://github.com/apache/cocoon
Java | 307 lines | 208 code | 40 blank | 59 comment | 43 complexity | 0573aadadc7f111cc1a41d875570cf79 MD5 | raw file
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package org.apache.cocoon.webapps.authentication.components;
  18. import java.io.IOException;
  19. import org.apache.avalon.framework.activity.Disposable;
  20. import org.apache.avalon.framework.service.ServiceException;
  21. import org.apache.avalon.framework.service.ServiceManager;
  22. import org.apache.avalon.framework.service.Serviceable;
  23. import org.apache.avalon.framework.thread.ThreadSafe;
  24. import org.apache.excalibur.source.Source;
  25. import org.apache.excalibur.source.SourceException;
  26. import org.apache.excalibur.source.SourceParameters;
  27. import org.apache.excalibur.source.SourceResolver;
  28. import org.apache.cocoon.ProcessingException;
  29. import org.apache.cocoon.components.source.SourceUtil;
  30. import org.apache.cocoon.util.AbstractLogEnabled;
  31. import org.apache.cocoon.webapps.authentication.configuration.HandlerConfiguration;
  32. import org.apache.cocoon.webapps.authentication.user.UserHandler;
  33. import org.apache.cocoon.webapps.session.MediaManager;
  34. import org.apache.cocoon.xml.XMLUtils;
  35. import org.apache.cocoon.xml.dom.DOMUtil;
  36. import org.w3c.dom.Document;
  37. import org.w3c.dom.Element;
  38. import org.w3c.dom.Node;
  39. import org.w3c.dom.NodeList;
  40. import org.w3c.dom.Text;
  41. import org.xml.sax.SAXException;
  42. /**
  43. * Verify if a user can be authenticated.
  44. *
  45. * @deprecated This block is deprecated and will be removed in future versions.
  46. * @version $Id$
  47. */
  48. public class PipelineAuthenticator extends AbstractLogEnabled
  49. implements Serviceable, ThreadSafe, Disposable, Authenticator {
  50. /** The service manager */
  51. protected ServiceManager manager;
  52. /** The source resolver */
  53. protected SourceResolver resolver;
  54. /**
  55. * Check the fragment if it is valid
  56. */
  57. private boolean isValidAuthenticationFragment(Document authenticationFragment)
  58. throws ProcessingException {
  59. // calling method is synced
  60. if (getLogger().isDebugEnabled() ) {
  61. getLogger().debug("BEGIN isValidAuthenticationFragment fragment=" +
  62. XMLUtils.serializeNode(authenticationFragment));
  63. }
  64. boolean isValid = false;
  65. // authenticationFragment must only have exactly one child with
  66. // the name authentication
  67. if (authenticationFragment.hasChildNodes()
  68. && authenticationFragment.getChildNodes().getLength() == 1) {
  69. Node child = authenticationFragment.getFirstChild();
  70. if (child.getNodeType() == Node.ELEMENT_NODE
  71. && child.getNodeName().equals("authentication")) {
  72. // now authentication must have one child ID
  73. if (child.hasChildNodes()) {
  74. NodeList children = child.getChildNodes();
  75. boolean found = false;
  76. int i = 0;
  77. int l = children.getLength();
  78. while (!found && i < l) {
  79. child = children.item(i);
  80. if (child.getNodeType() == Node.ELEMENT_NODE
  81. && child.getNodeName().equals("ID")) {
  82. found = true;
  83. } else {
  84. i++;
  85. }
  86. }
  87. // now the last check: ID must have a TEXT child
  88. if (found) {
  89. child.normalize(); // join text nodes
  90. if (child.hasChildNodes() &&
  91. child.getChildNodes().getLength() == 1 &&
  92. child.getChildNodes().item(0).getNodeType() == Node.TEXT_NODE) {
  93. String value = child.getChildNodes().item(0).getNodeValue().trim();
  94. if (value.length() > 0) isValid = true;
  95. }
  96. }
  97. }
  98. }
  99. }
  100. if (this.getLogger().isDebugEnabled()) {
  101. this.getLogger().debug("END isValidAuthenticationFragment valid=" + isValid);
  102. }
  103. return isValid;
  104. }
  105. /* (non-Javadoc)
  106. * @see org.apache.cocoon.webapps.authentication.components.Authenticator#authenticate(org.apache.cocoon.webapps.authentication.configuration.HandlerConfiguration, org.apache.excalibur.source.SourceParameters)
  107. */
  108. public AuthenticationResult authenticate(HandlerConfiguration configuration,
  109. SourceParameters parameters)
  110. throws ProcessingException {
  111. if (this.getLogger().isDebugEnabled() ) {
  112. this.getLogger().debug("start authenticator using handler " + configuration.getName());
  113. }
  114. final String authenticationResourceName = configuration.getAuthenticationResource();
  115. final SourceParameters authenticationParameters = configuration.getAuthenticationResourceParameters();
  116. if (parameters != null) {
  117. parameters.add(authenticationParameters);
  118. } else {
  119. parameters = authenticationParameters;
  120. }
  121. Document doc = null;
  122. String exceptionMsg = null;
  123. // invoke the source
  124. try {
  125. Source source = null;
  126. try {
  127. source = SourceUtil.getSource(authenticationResourceName, null,
  128. parameters, this.resolver);
  129. doc = SourceUtil.toDOM(source);
  130. } catch (SAXException se) {
  131. throw new ProcessingException(se);
  132. } catch (SourceException se) {
  133. throw SourceUtil.handle(se);
  134. } catch (IOException e) {
  135. throw new ProcessingException(e);
  136. } finally {
  137. this.resolver.release(source);
  138. }
  139. } catch (ProcessingException local) {
  140. this.getLogger().error("authenticator: " + local.getMessage(), local);
  141. exceptionMsg = local.getMessage();
  142. }
  143. // test if authentication was successful
  144. boolean isValid = false;
  145. AuthenticationResult result = null;
  146. if (doc != null) {
  147. isValid = this.isValidAuthenticationFragment( doc );
  148. if ( isValid ) {
  149. if (this.getLogger().isInfoEnabled() ) {
  150. this.getLogger().info("Authenticator: User authenticated using handler '"
  151. + configuration.getName() + "'");
  152. }
  153. MediaManager mediaManager = null;
  154. String mediaType;
  155. try {
  156. mediaManager = (MediaManager)this.manager.lookup( MediaManager.ROLE );
  157. mediaType = mediaManager.getMediaType();
  158. } catch (ServiceException se) {
  159. throw new ProcessingException("Unable to lookup media manager.", se);
  160. } finally {
  161. this.manager.release( mediaManager );
  162. }
  163. synchronized (configuration) {
  164. // add special nodes to the authentication block:
  165. // useragent, type and media
  166. Element specialElement;
  167. Text specialValue;
  168. Element authNode;
  169. authNode = (Element)doc.getFirstChild();
  170. specialElement = doc.createElementNS(null, "type");
  171. specialValue = doc.createTextNode("cocoon.authentication");
  172. specialElement.appendChild(specialValue);
  173. authNode.appendChild(specialElement);
  174. specialElement = doc.createElementNS(null, "media");
  175. specialValue = doc.createTextNode(mediaType);
  176. specialElement.appendChild(specialValue);
  177. authNode.appendChild(specialElement);
  178. result = new AuthenticationResult(true, doc);
  179. } // end sync
  180. }
  181. }
  182. if ( !isValid ) {
  183. if (this.getLogger().isInfoEnabled() ) {
  184. this.getLogger().info("Authenticator: Failed authentication using handler '"
  185. + configuration.getName()+ "'");
  186. }
  187. // get the /authentication/data Node if available
  188. Node data = null;
  189. if (doc != null) {
  190. data = DOMUtil.getFirstNodeFromPath(doc,
  191. new String[] {"authentication","data"},
  192. false);
  193. }
  194. doc = DOMUtil.createDocument();
  195. // now create the following xml:
  196. // <root>
  197. // <failed/>
  198. // if data is available data is included, otherwise:
  199. // <data>No information</data>
  200. // If exception message contains info, it is included into failed
  201. // </root>
  202. final Element root = doc.createElementNS(null, "root");
  203. doc.appendChild(root);
  204. Element element = doc.createElementNS(null, "failed");
  205. root.appendChild(element);
  206. if (exceptionMsg != null) {
  207. Text text = doc.createTextNode(exceptionMsg);
  208. element.appendChild(text);
  209. }
  210. if (data == null) {
  211. element = doc.createElementNS(null, "data");
  212. root.appendChild(element);
  213. Text text = doc.createTextNode("No information available");
  214. element.appendChild(text);
  215. } else {
  216. root.appendChild(doc.importNode(data, true));
  217. }
  218. result = new AuthenticationResult(false, doc);
  219. }
  220. if (this.getLogger().isDebugEnabled() ) {
  221. this.getLogger().debug("end authenticator");
  222. }
  223. return result;
  224. }
  225. /* (non-Javadoc)
  226. * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
  227. */
  228. public void service(ServiceManager manager) throws ServiceException {
  229. this.manager = manager;
  230. this.resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
  231. }
  232. /* (non-Javadoc)
  233. * @see org.apache.avalon.framework.activity.Disposable#dispose()
  234. */
  235. public void dispose() {
  236. if ( this.manager != null ){
  237. this.manager.release( this.resolver );
  238. this.manager = null;
  239. this.resolver = null;
  240. }
  241. }
  242. /* (non-Javadoc)
  243. * @see org.apache.cocoon.webapps.authentication.components.Authenticator#logout(UserHandler)
  244. */
  245. public void logout(UserHandler handler) {
  246. if (this.getLogger().isDebugEnabled() ) {
  247. this.getLogger().debug("logout using handler " + handler.getHandlerName());
  248. }
  249. final HandlerConfiguration configuration = handler.getHandlerConfiguration();
  250. final String logoutResourceName = configuration.getLogoutResource();
  251. if (logoutResourceName != null) {
  252. final SourceParameters parameters = configuration.getAuthenticationResourceParameters();
  253. // invoke the source
  254. Source source = null;
  255. try {
  256. // This allows arbitrary business logic to be called. Whatever is returned
  257. // is ignored.
  258. source = SourceUtil.getSource(logoutResourceName, null, parameters, this.resolver);
  259. SourceUtil.toDOM(source);
  260. } catch (Exception ignore) {
  261. this.getLogger().error("logout: " + ignore.getMessage(), ignore);
  262. } finally {
  263. this.resolver.release(source);
  264. }
  265. }
  266. }
  267. }