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