Coverage Report - org.kuali.student.security.kim.KimAuthenticationProvider
 
Classes in this File Line Coverage Branch Coverage Complexity
KimAuthenticationProvider
0%
0/37
0%
0/16
2.4
 
 1  
 /**
 2  
  * Copyright 2010 The Kuali Foundation Licensed under the
 3  
  * Educational Community License, Version 2.0 (the "License"); you may
 4  
  * not use this file except in compliance with the License. You may
 5  
  * obtain a copy of the License at
 6  
  *
 7  
  * http://www.osedu.org/licenses/ECL-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing,
 10  
  * software distributed under the License is distributed on an "AS IS"
 11  
  * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 12  
  * or implied. See the License for the specific language governing
 13  
  * permissions and limitations under the License.
 14  
  */
 15  
 
 16  
 package org.kuali.student.security.kim;
 17  
 
 18  
 import org.kuali.rice.core.config.Config;
 19  
 import org.kuali.rice.core.config.ConfigContext;
 20  
 import org.kuali.student.security.spring.KSRiceDefaultUserDetailsService;
 21  
 import org.springframework.dao.DataAccessException;
 22  
 import org.springframework.security.AuthenticationException;
 23  
 import org.springframework.security.AuthenticationServiceException;
 24  
 import org.springframework.security.BadCredentialsException;
 25  
 import org.springframework.security.providers.AuthenticationProvider;
 26  
 import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
 27  
 import org.springframework.security.providers.dao.AbstractUserDetailsAuthenticationProvider;
 28  
 import org.springframework.security.providers.dao.DaoAuthenticationProvider;
 29  
 import org.springframework.security.providers.dao.SaltSource;
 30  
 import org.springframework.security.providers.encoding.PasswordEncoder;
 31  
 import org.springframework.security.providers.encoding.PlaintextPasswordEncoder;
 32  
 import org.springframework.security.userdetails.UserDetails;
 33  
 import org.springframework.security.userdetails.UserDetailsService;
 34  
 import org.springframework.util.Assert;
 35  
 
 36  
 /**
 37  
  * An {@link AuthenticationProvider} implementation that retrieves user details
 38  
  * from an {@link UserDetailsService}. Slightly modified from {@link DaoAuthenticationProvider}
 39  
  * 
 40  
  * @author Kuali Student Team
 41  
  *
 42  
  */
 43  0
 public class KimAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
 44  
     
 45  
     //~ Instance fields ================================================================================================
 46  
 
 47  0
     private PasswordEncoder passwordEncoder = new PlaintextPasswordEncoder();
 48  
 
 49  
     private SaltSource saltSource;
 50  
 
 51  
     private UserDetailsService userDetailsService;
 52  
 
 53  0
     private boolean includeDetailsObject = true;
 54  
 
 55  
     //~ Methods ========================================================================================================
 56  
 
 57  
     protected void additionalAuthenticationChecks(UserDetails userDetails,
 58  
             UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
 59  0
         Object salt = null;
 60  0
         Config config = ConfigContext.getCurrentContextConfig();
 61  0
         String ksIgnoreRiceLogin = config.getProperty("ks.ignore.rice.login");
 62  
         
 63  
         // We skip the salt value since the password won't match when people are testing.
 64  
         // I do have a concern... the context of this attribute, does it imply use another authentication handler ?
 65  
         // I ask since Rice is used 2 determine the workflows...
 66  0
         if(!Boolean.valueOf(ksIgnoreRiceLogin)){
 67  0
                 if (this.saltSource != null) {
 68  0
                     salt = this.saltSource.getSalt(userDetails);
 69  
                 }
 70  
         
 71  0
                 if (authentication.getCredentials() == null) {
 72  0
                     throw new BadCredentialsException(messages.getMessage(
 73  
                             "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"),
 74  
                             includeDetailsObject ? userDetails : null);
 75  
                 }
 76  
         
 77  0
                 String presentedPassword = authentication.getCredentials().toString();
 78  
         
 79  0
                 if (!passwordEncoder.isPasswordValid(userDetails.getPassword(), presentedPassword, salt)) {
 80  0
                     throw new BadCredentialsException(messages.getMessage(
 81  
                             "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"),
 82  
                             includeDetailsObject ? userDetails : null);
 83  
                 }
 84  
         }
 85  0
     }
 86  
 
 87  
     protected void doAfterPropertiesSet() throws Exception {
 88  0
         Assert.notNull(this.userDetailsService, "A UserDetailsService must be set");
 89  0
     }
 90  
 
 91  
     protected final UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
 92  
             throws AuthenticationException {
 93  
         UserDetails loadedUser;
 94  
 
 95  0
         UserDetailsService ksRiceDefaultUserDetailsService = this.getUserDetailsService();
 96  0
         if(!(ksRiceDefaultUserDetailsService instanceof KSRiceDefaultUserDetailsService)){
 97  0
             throw new AuthenticationServiceException(
 98  
                 "UserDetailsService is not an an instance of KSRiceDefaultUserDetailsService");
 99  
         }
 100  
         
 101  
         try {
 102  
             //loadedUser = this.getUserDetailsService().loadUserByUsername(username);
 103  0
             loadedUser = ((KSRiceDefaultUserDetailsService)ksRiceDefaultUserDetailsService).loadUserByUsernameAndToken(username, authentication);
 104  
         }
 105  0
         catch (DataAccessException repositoryProblem) {
 106  0
             throw new AuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem);
 107  0
         }
 108  
 
 109  0
         if (loadedUser == null) {
 110  0
             throw new AuthenticationServiceException(
 111  
                     "UserDetailsService returned null, which is an interface contract violation");
 112  
         }
 113  0
         return loadedUser;
 114  
     }
 115  
 
 116  
     /**
 117  
      * Sets the PasswordEncoder instance to be used to encode and validate passwords.
 118  
      * If not set, {@link PlaintextPasswordEncoder} will be used by default.
 119  
      *
 120  
      * @param passwordEncoder The passwordEncoder to use
 121  
      */
 122  
     public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
 123  0
         this.passwordEncoder = passwordEncoder;
 124  0
     }
 125  
 
 126  
     protected PasswordEncoder getPasswordEncoder() {
 127  0
         return passwordEncoder;
 128  
     }
 129  
 
 130  
     /**
 131  
      * The source of salts to use when decoding passwords. <code>null</code>
 132  
      * is a valid value, meaning the <code>DaoAuthenticationProvider</code>
 133  
      * will present <code>null</code> to the relevant <code>PasswordEncoder</code>.
 134  
      *
 135  
      * @param saltSource to use when attempting to decode passwords via the <code>PasswordEncoder</code>
 136  
      */
 137  
     public void setSaltSource(SaltSource saltSource) {
 138  0
         this.saltSource = saltSource;
 139  0
     }
 140  
 
 141  
     protected SaltSource getSaltSource() {
 142  0
         return saltSource;
 143  
     }
 144  
 
 145  
     public void setUserDetailsService(UserDetailsService userDetailsService) {
 146  0
         this.userDetailsService = userDetailsService;
 147  0
     }
 148  
 
 149  
     protected UserDetailsService getUserDetailsService() {
 150  0
         return userDetailsService;
 151  
     }
 152  
 
 153  
     protected boolean isIncludeDetailsObject() {
 154  0
         return includeDetailsObject;
 155  
     }
 156  
 }