View Javadoc

1   /*
2    * Copyright 2007-2008 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.kuali.rice.kim.client.acegi;
18  
19  import java.io.StringReader;
20  
21  import javax.xml.parsers.DocumentBuilder;
22  import javax.xml.parsers.DocumentBuilderFactory;
23  
24  import org.acegisecurity.AuthenticationServiceException;
25  import org.acegisecurity.BadCredentialsException;
26  import org.acegisecurity.providers.cas.TicketResponse;
27  import org.acegisecurity.providers.cas.ticketvalidator.CasProxyTicketValidator;
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.kuali.rice.kim.sesn.DistributedSession;
31  import org.w3c.dom.Document;
32  import org.w3c.dom.Element;
33  import org.w3c.dom.NodeList;
34  import org.xml.sax.InputSource;
35  
36  import edu.yale.its.tp.cas.client.ProxyTicketValidator;
37  
38  
39  /**
40   * Uses CAS' <code>ProxyTicketValidator</code> to validate a service ticket.  
41   * Creates the distributed session.  Session principal is currently 
42   * user@method.
43   *  
44   * @author Kuali Rice Team (rice.collab@kuali.org)
45   *
46   */
47  public class KualiCasProxyTicketValidator extends CasProxyTicketValidator {
48      //~ Static fields/initializers =====================================================================================
49  
50      private static final Log logger = LogFactory.getLog(KualiCasProxyTicketValidator.class);
51  
52      private DistributedSession distributedSession;
53      //~ Instance fields ================================================================================================
54  
55  
56      /**
57       * This overridden method gets the authentication source and 
58       * Distributed Session Ticket from the response
59       * 
60       * @see org.acegisecurity.providers.cas.ticketvalidator.CasProxyTicketValidator#validateNow(edu.yale.its.tp.cas.client.ProxyTicketValidator)
61       */
62      protected TicketResponse validateNow(ProxyTicketValidator pv)
63          throws AuthenticationServiceException, BadCredentialsException {
64  		String					sAuthenticationSource = null;
65  		String                  sDST = null;
66  
67          try {
68              pv.validate();
69          } catch (Exception internalProxyTicketValidatorProblem) {
70              throw new AuthenticationServiceException(internalProxyTicketValidatorProblem.getMessage());
71          }
72  
73          if (!pv.isAuthenticationSuccesful()) {
74              throw new BadCredentialsException(pv.getErrorCode() + ": " + pv.getErrorMessage());
75          }
76          
77          logger.debug("PROXY RESPONSE: " + pv.getResponse());
78          
79          if (logger.isDebugEnabled()) {
80              logger.debug("DEBUG");
81          }
82                  
83          try {
84  			DocumentBuilderFactory	factory = DocumentBuilderFactory.newInstance();
85  			DocumentBuilder			builder = factory.newDocumentBuilder();
86  			InputSource inStream = new InputSource();
87  			inStream.setCharacterStream(new StringReader(pv.getResponse()));
88  			Document				doc     = builder.parse(inStream);
89  			Element 				head = doc.getDocumentElement();
90  			NodeList 				attrs = head.getElementsByTagName("cas:attribute");
91  			for (int i=0; i<attrs.getLength(); i++) {
92  				logger.debug(("Field name:" + ((Element)attrs.item(i)).getAttribute("name")) + "=" + ((Element)attrs.item(i)).getAttribute("value"));
93  				if ( ((Element)attrs.item(i)).getAttribute("name").equals("authenticationMethod") ) {
94  					sAuthenticationSource = ((Element)attrs.item(i)).getAttribute("value");
95  				} else if ( ((Element)attrs.item(i)).getAttribute("name").equals("DST") ) {
96  				    sDST = ((Element)attrs.item(i)).getAttribute("value");
97  				}
98  			}
99  			if (sAuthenticationSource != null && sDST != null) {
100                 String sPrincipal = pv.getUser() + "@" + sAuthenticationSource;
101 
102                 if (logger.isDebugEnabled()) {
103 			        logger.debug("Updating session: " + sDST + " " + sPrincipal);
104 			    }
105 // Touching here may be overkill since it should happen in the filter
106                 distributedSession.touchSesn(sDST);
107               //  distributedSession.addPrincipalToSesn(sDST, sPrincipal);
108 			} else {
109 			    if (logger.isDebugEnabled()) {
110                     logger.debug("Incomplete data from CAS:" + sAuthenticationSource + ":" + sDST);
111                 }
112 			}
113         } catch (Exception e) {
114         	logger.error("Error parsing CAS Result", e);
115         }
116         
117         logger.debug("Authentication Method:" + sAuthenticationSource);
118         return new KualiTicketResponse(pv.getUser(), pv.getProxyList(), pv.getPgtIou(), sDST);
119     }
120 
121 
122     /**
123      * @param distributedSession the distributedSession to set
124      */
125     public void setDistributedSession(DistributedSession distributedSession) {
126         this.distributedSession = distributedSession;
127     }
128     
129 
130 }