
CAS Authentication with Liferay(Liferay6.1-GA2) database using Mysql (without ldap).
Download CAS-EE that is available in .lpkg file from Liferay marketplace. In a production environment The CAS server should run on its own tomcat instance but for testing purpose we will drop it in the same instance as our Liferay portal. Download Liferay6.1-EE-GA2 bundle, extract it. Edit the server.xml file in tomcat, uncomments the SSL section to enable port 8443, as follows:
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true maxThreads="150" scheme="https" secure="true" disableUploadTimeout="true" enableLookups="false" clientAuth="false" sslProtocol="TLS" />
Generate the ssl certificate with java keytool using the following URL. http://www.liferay.com/community/wiki/-/wiki/Main/CAS+Liferay+6+Integration After that Start Liferay6.1-EE-GA2 server and deploy cas-web.war inside deploy folder. After deployment stop the server. Change configuration inside webapps/cas-web/WEB-INF/deployerConfigContext.xml. By default CAS is using SimpleTestUsernamePasswordAuthenticationHandler. Replace the above mentioned authentication handler inside authenticationhandlers property like structure mention below.
<property name="authenticationHandlers"> <list> <!--| This is the authentication handler that authenticates services by means of callback via SSL, thereby validating a server side SSL certificate. --> <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" p:httpClient-ref="httpClient" /> <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"> <property name="dataSource" ref="dataSource" /> <property name="sql" value="SELECT password_ FROM User_ WHERE screenName=?" /> <property name="passwordEncoder"> <bean class="com.liferay.LiferayPasswordEncoder"> </bean> </property> </bean> </list> </property> </bean> <!-- after closing of authenticationManager bean --> <!-- place database information settings --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName"> <value>com.mysql.jdbc.Driver</value> </property> <property name="url"> <value>jdbc:mysql://localhost:3306/lportal</value> </property> <property name="username"> <value>root</value> </property> <property name="password"> <value>root</value> </property> <property name="initialSize" value="1"></property> <property name="maxIdle" value="5"></property> <property name="maxActive" value="50"></property> <property name="maxWait" value="10000"></property> <property name="validationQuery" value="select 1"></property> <property name="testOnBorrow" value="false"></property> <property name="testWhileIdle" value="true"></property><property name="timeBetweenEvictionRunsMillis"value="10000"></property> <property name="minEvictableIdleTimeMillis" value="30000"></property><property name="numTestsPerEvictionRun" value="-1"></property></bean> //
Create LiferayPassword Encoder class that will implements PasswordEncoder (While compiling it will need cas-server-core-3.3.5.jar that is available inside cas-web/WEB-INF/lib) package com.liferay;
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.io.UnsupportedEncodingException; import org.jasig.cas.authentication.handler.PasswordEncoder; public final class LiferayPasswordEncoder implements PasswordEncoder { public String encode(final String password) { MessageDigest digester = null; try{ digester = MessageDigest.getInstance("SHA"); digester.update(password.getBytes("UTF-8")); } catch (NoSuchAlgorithmException ex) { System.out.println("encode method exception”+ ex.printStackTrace()); } catch (UnsupportedEncodingException ex) { System.out.println("encode method exception”+ ex.printStackTrace()); } byte[] bytes = digester.digest(); return encodeBase64(bytes); } private static char getChar(int sixbit) { if (sixbit >= 0 && sixbit <= 25) { return (char)(65 + sixbit); } if (sixbit >= 26 && sixbit <= 51) { return (char)(97 + (sixbit - 26)); } if (sixbit >= 52 && sixbit <= 61) { return (char)(48 + (sixbit - 52)); } if (sixbit == 62) { return '+'; } return sixbit != 63 ? '?' : '/'; } private static String encodeBase64(byte raw[]) { StringBuilder encoded = new StringBuilder(); for (int i = 0; i < raw.length; i += 3) { encoded.append(encodeBlock(raw, i)); } return encoded.toString(); } private static char[] encodeBlock(byte raw[], int offset) { int block = 0; int slack = raw.length - offset - 1; int end = slack < 2 ? slack : 2; for (int i = 0; i <= end; i++) { byte b = raw[offset + i]; int neuter = b >= 0 ? ((int) (b)) : b + 256; block += neuter << 8 * (2 - i); } char base64[] = new char[4]; for (int i = 0; i < 4; i++) { int sixbit = block >>> 6 * (3 - i) & 0x3f; base64[ i ] = getChar(sixbit); } if (slack < 1) { base64[2] = '='; } if (slack < 2) { base64[3] = '='; } return base64; } }
After compiling keep LiferayPasswordEncoder.class inside \webapps\cas-web\WEB-INF\classes\com\liferay folder and add jar file mentioned below inside \webapps\cas-web\WEB-INF\lib . cas-server-jdbc-3.0.4.jar commons-dbcp-1.4.jar commons-pool.jar.
Now Start Liferay at localhost:8080 sign In with default username password with sign In portlet and go to control panel-->Portal Settings-->click on authentication --->click on cas-->check enable cas box Login Url:- https://localhost:8443/cas-web/login Logout Url:- https://localhost:8443/cas-web/logout Server Name:-localhost:8080 Server Url:- https://localhost:8443/cas-web No such user redirect Url:-http://localhost:8080 Click on Test cas configuration. It will show you pass for above three Urls. Click on save. Make the authentication by screen name in Portal SettingsGeneral. (By default it is By Email Address)
If you want to authenticate ByEmailAddress change the sql query in deployerConfigContext.xml as bellow.
<property name="sql" value="SELECT password_ FROM User_ WHERE emailAddress=?" />