Coverage Report - org.kuali.rice.kim.client.acegi.KualiCasAuthenticationProvider
 
Classes in this File Line Coverage Branch Coverage Complexity
KualiCasAuthenticationProvider
0%
0/33
0%
0/28
10.5
 
 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 org.acegisecurity.Authentication;
 20  
 import org.acegisecurity.AuthenticationException;
 21  
 import org.acegisecurity.BadCredentialsException;
 22  
 import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
 23  
 import org.acegisecurity.providers.cas.CasAuthenticationProvider;
 24  
 import org.acegisecurity.providers.cas.CasAuthenticationToken;
 25  
 import org.acegisecurity.providers.cas.StatelessTicketCache;
 26  
 import org.acegisecurity.ui.cas.CasProcessingFilter;
 27  
 import org.acegisecurity.userdetails.UserDetails;
 28  
 import org.apache.commons.logging.Log;
 29  
 import org.apache.commons.logging.LogFactory;
 30  
 
 31  
 /**
 32  
  * A {@link CasAuthenticationProvider} implementation that integrates with 
 33  
  * Kuali Identity Management (KIM).<p>This 
 34  
  * <code>CasAuthenticationProvider</code> is capable of validating {@link
 35  
  * UsernamePasswordAuthenticationToken} requests which contains a 
 36  
  * distributed session token. It can also validate a previously created 
 37  
  * {@link CasAuthenticationToken}.</p>
 38  
  *
 39  
  * Verifies the the <code>UserDetails</code> based on a valid CAS ticket 
 40  
  * response.
 41  
  * 
 42  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 43  
 */
 44  0
 public class KualiCasAuthenticationProvider extends CasAuthenticationProvider {
 45  
     
 46  0
     private static final Log logger = LogFactory.getLog(KualiCasAuthenticationProvider.class);
 47  
 
 48  
     /**
 49  
      * This overridden method is copied from CAS verbatim.  For some reason 
 50  
      * {@link authenticateNow} would not override and the super method 
 51  
      * would get called until did this method was also overridden.
 52  
      * 
 53  
      * @see org.acegisecurity.providers.cas.CasAuthenticationProvider#authenticate(org.acegisecurity.Authentication)
 54  
      */
 55  
     public Authentication authenticate(Authentication authentication) throws AuthenticationException {
 56  0
         StatelessTicketCache statelessTicketCache = this.getStatelessTicketCache();
 57  0
         String key = this.getKey();
 58  0
         if (!supports(authentication.getClass())) {
 59  0
             return null;
 60  
         }
 61  
 
 62  0
         if (authentication instanceof UsernamePasswordAuthenticationToken
 63  
             && (!CasProcessingFilter.CAS_STATEFUL_IDENTIFIER.equals(authentication.getPrincipal().toString())
 64  
             && !CasProcessingFilter.CAS_STATELESS_IDENTIFIER.equals(authentication.getPrincipal().toString()))) {
 65  
             // UsernamePasswordAuthenticationToken not CAS related
 66  0
             return null;
 67  
         }
 68  
 
 69  
         // If an existing CasAuthenticationToken, just check we created it
 70  0
         if (authentication instanceof CasAuthenticationToken) {
 71  0
             if (key.hashCode() == ((CasAuthenticationToken) authentication).getKeyHash()) {
 72  0
                 return authentication;
 73  
             } else {
 74  0
                 throw new BadCredentialsException(messages.getMessage("CasAuthenticationProvider.incorrectKey",
 75  
                         "The presented CasAuthenticationToken does not contain the expected key"));
 76  
             }
 77  
         }
 78  
 
 79  
         // Ensure credentials are presented
 80  0
         if ((authentication.getCredentials() == null) || "".equals(authentication.getCredentials())) {
 81  0
             throw new BadCredentialsException(messages.getMessage("CasAuthenticationProvider.noServiceTicket",
 82  
                     "Failed to provide a CAS service ticket to validate"));
 83  
         }
 84  
 
 85  0
         boolean stateless = false;
 86  
 
 87  0
         if (authentication instanceof UsernamePasswordAuthenticationToken
 88  
             && CasProcessingFilter.CAS_STATELESS_IDENTIFIER.equals(authentication.getPrincipal())) {
 89  0
             stateless = true;
 90  
         }
 91  
 
 92  0
         CasAuthenticationToken result = null;
 93  
 
 94  0
         if (stateless) {
 95  
             // Try to obtain from cache
 96  0
             result = statelessTicketCache.getByTicketId(authentication.getCredentials().toString());
 97  
         }
 98  
 
 99  0
         if (result == null) {
 100  0
             result = this.authenticateNow(authentication);
 101  0
             result.setDetails(authentication.getDetails());
 102  
         }
 103  
 
 104  0
         if (stateless) {
 105  
             // Add to cache
 106  0
             statelessTicketCache.putTicketInCache(result);
 107  
         }
 108  
 
 109  0
         return result;
 110  
     }
 111  
     
 112  
     /**
 113  
      * This overridden method is differs from the super method by 
 114  
      * populating the user details by passing the full response
 115  
      * 
 116  
      * @see org.acegisecurity.providers.cas.CasAuthenticationProvider#authenticateNow(Authentication authentication)
 117  
      */
 118  
     private CasAuthenticationToken authenticateNow(Authentication authentication) throws AuthenticationException {
 119  
         // Validate
 120  0
         KualiTicketResponse response = (KualiTicketResponse)this.getTicketValidator().confirmTicketValid(authentication.getCredentials().toString());
 121  
 
 122  
         // Check proxy list is trusted
 123  0
         this.getCasProxyDecider().confirmProxyListTrusted(response.getProxyList());
 124  0
         if (logger.isDebugEnabled()) {
 125  0
             logger.debug("authenticationNOW:" + response);
 126  
         }
 127  
         // Lookup user details      
 128  0
         logger.debug("\n\npopulating authorities\n\n");
 129  0
         UserDetails userDetails = ((KualiCasAuthoritiesPopulator)this.getCasAuthoritiesPopulator()).getUserDetails(response);        
 130  
 
 131  
         // Construct CasAuthenticationToken
 132  0
         return new CasAuthenticationToken(this.getKey(), userDetails, authentication.getCredentials(),
 133  
             userDetails.getAuthorities(), userDetails, response.getProxyList(), response.getProxyGrantingTicketIou());
 134  
     }
 135  
 }