View Javadoc

1   /* Copyright 2004 Acegi Technology Pty Limited
2    *
3    * Licensed under the Apache License, Version 2.0 (the "License");
4    * you may not use this file except in compliance with the License.
5    * You may obtain a copy of the License at
6    *
7    *     http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  
16  package org.acegisecurity.providers.cas.ticketvalidator;
17  
18  import edu.yale.its.tp.cas.client.ProxyTicketValidator;
19  
20  import org.acegisecurity.AuthenticationException;
21  import org.acegisecurity.AuthenticationServiceException;
22  import org.acegisecurity.BadCredentialsException;
23  import org.acegisecurity.providers.cas.TicketResponse;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  
28  
29  /***
30   * Uses CAS' <code>ProxyTicketValidator</code> to validate a service ticket.
31   *
32   * @author Ben Alex
33   * @version $Id: CasProxyTicketValidator.java,v 1.2 2005/11/17 00:56:29 benalex Exp $
34   */
35  public class CasProxyTicketValidator extends AbstractTicketValidator {
36      //~ Static fields/initializers =============================================
37  
38      private static final Log logger = LogFactory.getLog(CasProxyTicketValidator.class);
39  
40      //~ Instance fields ========================================================
41  
42      private String proxyCallbackUrl;
43  
44      //~ Methods ================================================================
45  
46      public void setProxyCallbackUrl(String proxyCallbackUrl) {
47          this.proxyCallbackUrl = proxyCallbackUrl;
48      }
49  
50      /***
51       * Optional callback URL to obtain a proxy-granting ticket from CAS.
52       * 
53       * <P>
54       * This callback URL belongs to the Acegi Security System for Spring
55       * secured application. We suggest you use CAS'
56       * <code>ProxyTicketReceptor</code> servlet to receive this callback and
57       * manage the proxy-granting ticket list. The callback URL is usually
58       * something like
59       * <code>https://www.mycompany.com/application/casProxy/receptor</code>.
60       * </p>
61       * 
62       * <P>
63       * If left <code>null</code>, the <code>CasAuthenticationToken</code> will
64       * not have a proxy granting ticket IOU and there will be no
65       * proxy-granting ticket callback. Accordingly, the Acegi Securty System
66       * for Spring secured application will be unable to obtain a proxy ticket
67       * to call another CAS-secured service on behalf of the user. This is not
68       * really an issue for most applications.
69       * </p>
70       *
71       * @return the proxy callback URL, or <code>null</code> if not used
72       */
73      public String getProxyCallbackUrl() {
74          return proxyCallbackUrl;
75      }
76  
77      public TicketResponse confirmTicketValid(String serviceTicket)
78          throws AuthenticationException {
79          // Attempt to validate presented ticket using CAS' ProxyTicketValidator class
80          ProxyTicketValidator pv = new ProxyTicketValidator();
81  
82          pv.setCasValidateUrl(super.getCasValidate());
83          pv.setServiceTicket(serviceTicket);
84          pv.setService(super.getServiceProperties().getService());
85  
86          if (super.getServiceProperties().isSendRenew()) {
87              logger.warn(
88                  "The current CAS ProxyTicketValidator does not support the 'renew' property. The ticket cannot be validated as having been issued by a 'renew' authentication. It is expected this will be corrected in a future version of CAS' ProxyTicketValidator.");
89          }
90  
91          if ((this.proxyCallbackUrl != null)
92              && (!"".equals(this.proxyCallbackUrl))) {
93              pv.setProxyCallbackUrl(proxyCallbackUrl);
94          }
95  
96          return validateNow(pv);
97      }
98  
99      /***
100      * Perform the actual remote invocation. Protected to enable replacement
101      * during tests.
102      *
103      * @param pv the populated <code>ProxyTicketValidator</code>
104      *
105      * @return the <code>TicketResponse</code>
106      *
107      * @throws AuthenticationServiceException
108      *         if<code>ProxyTicketValidator</code> internally fails
109      * @throws BadCredentialsException DOCUMENT ME!
110      */
111     protected TicketResponse validateNow(ProxyTicketValidator pv)
112         throws AuthenticationServiceException, BadCredentialsException {
113         try {
114             pv.validate();
115         } catch (Exception internalProxyTicketValidatorProblem) {
116             throw new AuthenticationServiceException(internalProxyTicketValidatorProblem
117                 .getMessage());
118         }
119 
120         if (!pv.isAuthenticationSuccesful()) {
121             throw new BadCredentialsException(pv.getErrorCode() + ": "
122                 + pv.getErrorMessage());
123         }
124 
125         return new TicketResponse(pv.getUser(), pv.getProxyList(),
126             pv.getPgtIou());
127     }
128 }