Help with migrating CAS 4.x to 5.x

196 views
Skip to first unread message

Nick Thacker

unread,
Mar 21, 2018, 3:36:23 PM3/21/18
to CAS Community
Hi all,

I know this has been posted before (https://groups.google.com/a/apereo.org/forum/?utm_medium=email&utm_source=footer#!msg/cas-user/hmtHSpsYhLE/dXhzQSNJAAAJ), but I am still having a hard time upgrading our CAS 4.x to 5.x.  I have not worked much in the Spring Framework and Spring Boot, so I'm still fresh to much of the inner workings of it.

A previous developer had set up CAS 4.x with a custom authentication handler for our application environment.  Please see the code for the handler and deployerConfigContext.xml:

deployerConfigContext.xml:
    <util:map id="authenticationHandlersResolvers">
       
<entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
       
<entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" />
   
</util:map>
 
 


   
<util:list id="authenticationMetadataPopulators">
       
<ref bean="successfulHandlerMetaDataPopulator" />
       
<ref bean="rememberMeAuthenticationMetaDataPopulator" />
   
</util:list>


   
<bean id="attributeRepository" class="org.jasig.services.persondir.support.NamedStubPersonAttributeDao"
         
p:backingMap-ref="attrRepoBackingMap" />


   
<alias name="acceptUsersAuthenticationHandler" alias="primaryAuthenticationHandler" />
   
<alias name="personDirectoryPrincipalResolver" alias="primaryPrincipalResolver" />


   
<util:map id="attrRepoBackingMap">
       
<entry key="uid" value="uid" />
       
<entry key="eduPersonAffiliation" value="eduPersonAffiliation" />
       
<entry key="groupMembership" value="groupMembership" />
       
<entry>
           
<key><value>memberOf</value></key>
           
<list>
               
<value>faculty</value>
               
<value>staff</value>
               
<value>org</value>
           
</list>
       
</entry>
   
</util:map>


   
<alias name="serviceThemeResolver" alias="themeResolver" />


   
<alias name="jsonServiceRegistryDao" alias="serviceRegistryDao" />


   
<alias name="ehcacheTicketRegistry" alias="ticketRegistry" />


   
<alias name="ticketGrantingTicketExpirationPolicy" alias="grantingTicketExpirationPolicy" />
   
<alias name="multiTimeUseOrTimeoutExpirationPolicy" alias="serviceTicketExpirationPolicy" />


   
<alias name="anyAuthenticationPolicy" alias="authenticationPolicy" />
   
<alias name="acceptAnyAuthenticationPolicyFactory" alias="authenticationPolicyFactory" />


   
<bean id="auditTrailManager"
         
class="org.jasig.inspektr.audit.support.Slf4jLoggingAuditTrailManager"
         
p:entrySeparator="${cas.audit.singleline.separator:|}"
         
p:useSingleLine="${cas.audit.singleline:false}"/>


   
<alias name="neverThrottle" alias="authenticationThrottle" />


   
<util:list id="monitorsList">
       
<ref bean="memoryMonitor" />
       
<ref bean="sessionMonitor" />
   
</util:list>
 


   
<alias name="defaultPrincipalFactory" alias="principalFactory" />
   
<alias name="defaultAuthenticationTransactionManager" alias="authenticationTransactionManager" />
   
<alias name="defaultPrincipalElectionStrategy" alias="principalElectionStrategy" />
   
<alias name="tgcCipherExecutor" alias="defaultCookieCipherExecutor" />
 


 
 
<bean id="(customPasswordEncoder)" class="(classForPasswordEncoder)"/>
 
 
<bean id="DatabaseAuthenticationHandler" class="(classForCustomDatabaseHandler)">
 
<property name="principalFactory" ref="defaultPrincipalFactory"/>
 
<property name="passwordEncoder" ref="customPasswordEncoder"/>
 
<property name="dataSource">
 
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
 
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
 
<property name="url" value="(ourSqlInstance);"/>
 
</bean>
 
</property>
 
 
 
<alias name="dataSource" alias="queryEncodeDatabaseDataSource" />


 
<alias name="DatabaseAuthenticationHandler" alias="primaryAuthenticationHandler" />


CustomDatabaseHandler:
package example.apps.cas.authentication;


import java.security.GeneralSecurityException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import javax.security.auth.login.AccountNotFoundException;
import javax.security.auth.login.FailedLoginException;
import org.apache.commons.lang3.StringUtils;
import org.jasig.cas.authentication.BasicCredentialMetaData;
import org.jasig.cas.authentication.Credential;
import org.jasig.cas.authentication.DefaultHandlerResult;
import org.jasig.cas.authentication.HandlerResult;
import org.jasig.cas.authentication.MessageDescriptor;
import org.jasig.cas.authentication.PreventedException;
import org.jasig.cas.authentication.UsernamePasswordCredential;
import org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.principal.DefaultPrincipalFactory;
import org.jasig.cas.authentication.principal.Principal;
import org.apache.commons.dbcp.BasicDataSource;


import example.apps.cas.dao.UserDao;
import example.apps.cas.model.UserModel;


public class DatabaseAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler {


 
private DefaultPrincipalFactory principalFactory = null;
 
private BasicDataSource dataSource = null;


 
@Override
 
public boolean supports(Credential credentials) {
 
return credentials != null && UsernamePasswordCredential.class.isAssignableFrom(credentials.getClass());
 
}


 
@Override
 
protected HandlerResult authenticateUsernamePasswordInternal(UsernamePasswordCredential credentials)
 
throws GeneralSecurityException, PreventedException {


 
String username = credentials.getUsername().trim();
 
String password = credentials.getPassword();


 
UserDao userDao = new UserDao();
 
BasicDataSource dataSource = this.getDataSource();
 userDao
.setDataSource(dataSource);


 
// Throw exception if username is blank
 
if (StringUtils.isEmpty(username)) {
 
throw new AccountNotFoundException("Username can not be blank.");
 
}


 
// Throw exception if password is blank
 
if (StringUtils.isEmpty(password)) {
 
throw new FailedLoginException(String.format("Password can not be blank for user %s.", username));
 
}


 
// Throw exception if unable to select password from database
 
UserModel user = new UserModel();
 
try {
 user
= userDao.getUser(username);
 
} catch (SQLException e) {
 e
.printStackTrace();
 
throw new PreventedException(String.format("Unable to retrieve password from database for user %s."), e);
 
}


 
// Throw exception if user account does not exist in database
 
if (user == null) {
 
throw new AccountNotFoundException(String.format("Unable to find account for user %s.", username));
 
}


 
// Throw exception if password cannot be encrypted
 
String encryptedPassword = this.getPasswordEncoder().encode(password);
 
if (encryptedPassword == null) {
 
throw new PreventedException(String.format("Unable to encrypt user password for user %s.", username),
 
new NullPointerException("Encoded password is null."));
 
}


 
// Throw exception if password do not match
 
if (!encryptedPassword.equals(user.getEncryptedPassword())) {
 
throw new FailedLoginException(String.format("Failed to authenticate password for user %s", username));
 
}


 
UsernamePasswordCredential handlerCredentials = new UsernamePasswordCredential();
 handlerCredentials
.setUsername(username);
 handlerCredentials
.setUsername(password);

 


 
return this.createHandlerResult(handlerCredentials, this.getPrincipalFactory().createPrincipal(username), null);
 
}
 
 
 
@Override
 
public String getName() {
 
return "DatabaseAuthenticationHandler";
 
}
 


 
public DefaultPrincipalFactory getPrincipalFactory() {
 
return principalFactory;
 
}


 
public void setPrincipalFactory(DefaultPrincipalFactory principalFactory) {
 
this.principalFactory = principalFactory;
 
}


 
public BasicDataSource getDataSource() {
 
return dataSource;
 
}


 
public void setDataSource(BasicDataSource dataSource) {
 
this.dataSource = dataSource;
 
}


Now, I understand the best thing to do is to move this to some sort of Configuration file for Spring Boot.  I've also read https://apereo.github.io/2017/02/02/cas51-authn-handlers/.  I guess my questions are as follows:

1) Is there some documentation for individuals who are newer to Spring Framework, to help them create this configuration files?
2) I read that you can still use the deployerConfigContext.xml if need be.  Is there some documentation on handling how you can get this to work with 5.x?

Apologies if there is any repeated questions, and thanks for your help!

Nick

Man H

unread,
Mar 21, 2018, 7:08:34 PM3/21/18
to cas-...@apereo.org

--
- Website: https://apereo.github.io/cas
- Gitter Chatroom: https://gitter.im/apereo/cas
- List Guidelines: https://goo.gl/1VRrw7
- Contributions: https://goo.gl/mh7qDG
---
You received this message because you are subscribed to the Google Groups "CAS Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cas-user+unsubscribe@apereo.org.
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/d1dbfdb5-0821-44cf-a9b8-cef984b4695e%40apereo.org.

Reply all
Reply to author
Forward
0 new messages