Clover coverage report - Acegi Security System for Spring - 1.0.0-RC1
Coverage timestamp: Mon Dec 5 2005 09:05:15 EST
file stats: LOC: 216   Methods: 15
NCLOC: 141   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
CasAuthenticationProvider.java 100% 97.9% 93.3% 97.6%
coverage coverage
 1    /* Copyright 2004, 2005 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;
 17   
 18    import org.acegisecurity.AcegiMessageSource;
 19    import org.acegisecurity.Authentication;
 20    import org.acegisecurity.AuthenticationException;
 21    import org.acegisecurity.BadCredentialsException;
 22    import org.acegisecurity.providers.AuthenticationProvider;
 23    import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
 24    import org.acegisecurity.ui.cas.CasProcessingFilter;
 25    import org.acegisecurity.userdetails.UserDetails;
 26    import org.apache.commons.logging.Log;
 27    import org.apache.commons.logging.LogFactory;
 28    import org.springframework.beans.factory.InitializingBean;
 29    import org.springframework.context.MessageSource;
 30    import org.springframework.context.MessageSourceAware;
 31    import org.springframework.context.support.MessageSourceAccessor;
 32    import org.springframework.util.Assert;
 33   
 34   
 35    /**
 36    * An {@link AuthenticationProvider} implementation that integrates with Yale
 37    * Central Authentication Service (CAS).
 38    *
 39    * <p>
 40    * This <code>AuthenticationProvider</code> is capable of validating {@link
 41    * UsernamePasswordAuthenticationToken} requests which contain a
 42    * <code>principal</code> name equal to either {@link
 43    * CasProcessingFilter#CAS_STATEFUL_IDENTIFIER} or {@link
 44    * CasProcessingFilter#CAS_STATELESS_IDENTIFIER}. It can also validate a
 45    * previously created {@link CasAuthenticationToken}.
 46    * </p>
 47    */
 48    public class CasAuthenticationProvider implements AuthenticationProvider,
 49    InitializingBean, MessageSourceAware {
 50    //~ Static fields/initializers =============================================
 51   
 52    private static final Log logger = LogFactory.getLog(CasAuthenticationProvider.class);
 53   
 54    //~ Instance fields ========================================================
 55   
 56    private CasAuthoritiesPopulator casAuthoritiesPopulator;
 57    private CasProxyDecider casProxyDecider;
 58    protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor();
 59    private StatelessTicketCache statelessTicketCache;
 60    private String key;
 61    private TicketValidator ticketValidator;
 62   
 63    //~ Methods ================================================================
 64   
 65  12 public void afterPropertiesSet() throws Exception {
 66  12 Assert.notNull(this.casAuthoritiesPopulator,
 67    "A casAuthoritiesPopulator must be set");
 68  11 Assert.notNull(this.ticketValidator, "A ticketValidator must be set");
 69  10 Assert.notNull(this.casProxyDecider, "A casProxyDecider must be set");
 70  9 Assert.notNull(this.statelessTicketCache,
 71    "A statelessTicketCache must be set");
 72  8 Assert.notNull(key,
 73    "A Key is required so CasAuthenticationProvider can identify tokens it previously authenticated");
 74  7 Assert.notNull(this.messages, "A message source must be set");
 75    }
 76   
 77  8 public Authentication authenticate(Authentication authentication)
 78    throws AuthenticationException {
 79  8 if (!supports(authentication.getClass())) {
 80  1 return null;
 81    }
 82   
 83  7 if (authentication instanceof UsernamePasswordAuthenticationToken
 84    && (!CasProcessingFilter.CAS_STATEFUL_IDENTIFIER.equals(
 85    authentication.getPrincipal().toString())
 86    && !CasProcessingFilter.CAS_STATELESS_IDENTIFIER.equals(
 87    authentication.getPrincipal().toString()))) {
 88    // UsernamePasswordAuthenticationToken not CAS related
 89  1 return null;
 90    }
 91   
 92    // If an existing CasAuthenticationToken, just check we created it
 93  6 if (authentication instanceof CasAuthenticationToken) {
 94  2 if (this.key.hashCode() == ((CasAuthenticationToken) authentication)
 95    .getKeyHash()) {
 96  1 return authentication;
 97    } else {
 98  1 throw new BadCredentialsException(messages.getMessage(
 99    "CasAuthenticationProvider.incorrectKey",
 100    "The presented CasAuthenticationToken does not contain the expected key"));
 101    }
 102    }
 103   
 104    // Ensure credentials are presented
 105  4 if ((authentication.getCredentials() == null)
 106    || "".equals(authentication.getCredentials())) {
 107  1 throw new BadCredentialsException(messages.getMessage(
 108    "CasAuthenticationProvider.noServiceTicket",
 109    "Failed to provide a CAS service ticket to validate"));
 110    }
 111   
 112  3 boolean stateless = false;
 113   
 114  3 if (authentication instanceof UsernamePasswordAuthenticationToken
 115    && CasProcessingFilter.CAS_STATELESS_IDENTIFIER.equals(
 116    authentication.getPrincipal())) {
 117  2 stateless = true;
 118    }
 119   
 120  3 CasAuthenticationToken result = null;
 121   
 122  3 if (stateless) {
 123    // Try to obtain from cache
 124  2 result = statelessTicketCache.getByTicketId(authentication.getCredentials()
 125    .toString());
 126    }
 127   
 128  3 if (result == null) {
 129  2 result = this.authenticateNow(authentication);
 130    }
 131   
 132  3 if (stateless) {
 133    // Add to cache
 134  2 statelessTicketCache.putTicketInCache(result);
 135    }
 136   
 137  3 return result;
 138    }
 139   
 140  2 private CasAuthenticationToken authenticateNow(
 141    Authentication authentication) throws AuthenticationException {
 142    // Validate
 143  2 TicketResponse response = ticketValidator.confirmTicketValid(authentication.getCredentials()
 144    .toString());
 145   
 146    // Check proxy list is trusted
 147  2 this.casProxyDecider.confirmProxyListTrusted(response.getProxyList());
 148   
 149    // Lookup user details
 150  2 UserDetails userDetails = this.casAuthoritiesPopulator.getUserDetails(response
 151    .getUser());
 152   
 153    // Construct CasAuthenticationToken
 154  2 return new CasAuthenticationToken(this.key, response.getUser(),
 155    authentication.getCredentials(), userDetails.getAuthorities(),
 156    userDetails, response.getProxyList(),
 157    response.getProxyGrantingTicketIou());
 158    }
 159   
 160  1 public CasAuthoritiesPopulator getCasAuthoritiesPopulator() {
 161  1 return casAuthoritiesPopulator;
 162    }
 163   
 164  1 public CasProxyDecider getCasProxyDecider() {
 165  1 return casProxyDecider;
 166    }
 167   
 168  2 public String getKey() {
 169  2 return key;
 170    }
 171   
 172  1 public StatelessTicketCache getStatelessTicketCache() {
 173  1 return statelessTicketCache;
 174    }
 175   
 176  1 public TicketValidator getTicketValidator() {
 177  1 return ticketValidator;
 178    }
 179   
 180  11 public void setCasAuthoritiesPopulator(
 181    CasAuthoritiesPopulator casAuthoritiesPopulator) {
 182  11 this.casAuthoritiesPopulator = casAuthoritiesPopulator;
 183    }
 184   
 185  11 public void setCasProxyDecider(CasProxyDecider casProxyDecider) {
 186  11 this.casProxyDecider = casProxyDecider;
 187    }
 188   
 189  11 public void setKey(String key) {
 190  11 this.key = key;
 191    }
 192   
 193  0 public void setMessageSource(MessageSource messageSource) {
 194  0 this.messages = new MessageSourceAccessor(messageSource);
 195    }
 196   
 197  11 public void setStatelessTicketCache(
 198    StatelessTicketCache statelessTicketCache) {
 199  11 this.statelessTicketCache = statelessTicketCache;
 200    }
 201   
 202  13 public void setTicketValidator(TicketValidator ticketValidator) {
 203  13 this.ticketValidator = ticketValidator;
 204    }
 205   
 206  11 public boolean supports(Class authentication) {
 207  11 if (UsernamePasswordAuthenticationToken.class.isAssignableFrom(
 208    authentication)) {
 209  6 return true;
 210  5 } else if (CasAuthenticationToken.class.isAssignableFrom(authentication)) {
 211  3 return true;
 212    } else {
 213  2 return false;
 214    }
 215    }
 216    }