單點登陸(sso)的實作方式有很多種,這裡所說的是用cas實作,這也是liferay中所采納的方式。至于什麼是cas,單點登陸實作的原理等,這裡不做解釋(看上一個我轉載的文章),直接一步一步明說實作方式,好了,多一個字的費話也不說了。
第一步,建立證書
keytool -genkey -alias tomcat -keystore c:\mykeystore -dname "cn=xyb, ou=localhost, o=localhost, l=sh, st=sh, c=cn" -keypass 123456 -storepass 123456
ps:
-genkey 建立一個證書
-alias 證書的别名
-keystore 指定生成此證書的路徑(可不寫,預設存在系統的home目錄下.keystore檔案中
-storepass 指定密鑰庫的密碼
-keypass 指定别名條目的密碼
-dname 指定證書擁有者資訊(可不寫,但,系統會提示你依次輸入這些資訊,特别要注意“cn”的值是你想做為cas伺服器的這台機器的域名或機器名,但就是不能是ip)
-keyalg 指定密鑰的算法(可不寫)
-validity 指定建立的證書有效期多少天(可不寫,預設為90天)
第二步,導出證書
keytool -export -alias tomcat -keystore c:\mykeystore -file c:\mycerts.cer -storepass 123456
-export 将别名指定的證書導出到檔案
-keystore 指定生成此證書的路徑(上一步中寫的什麼這就寫什麼,如果沒寫,這也不寫)
-file 指定導出到檔案的檔案名
第三步,把導出的證書導入到用戶端伺服器
keytool -import -trustcacerts -alias tomcat -keystore "%java_home%/jre/lib/security/cacerts" -storepass 123456 -file c:\mycerts.cer
-import 将已簽名數字證書導入密鑰庫
-file 指定要導入到密鑰庫的檔案名(也就是上一步導出的那個檔案)
有一個提示:是否信任這個證書,輸入 y,回車。
第四步,下載下傳cas內建包。将下載下傳後的檔案改名為cas-web,放置在liferay的webapps目錄下,在conf/server.xml中找到下面這段,去掉原有的注釋并修改為:
<connector port="8443" maxhttpheadersize="8192" maxthreads="150" minsparethreads="25" maxsparethreads="75" enablelookups="false" disableuploadtimeout="true" acceptcount="100" scheme="https" secure="true" clientauth="false" sslprotocol="tls" uriencoding="utf-8" keystorepass="123456" keyalias="tomcat"/>
第五步,在liferay的webapps\root\web-inf\classes\portal-ext.properties下添加如下内容:
cas.auth.enabled=true
cas.login.url=https://xyb:8443/cas-web/login
cas.logout.url=https://xyb:8443/cas-web/logout
cas.server.name=用戶端ip:8080
cas.service.url=
#cas.service.url=http://localhost:8080/c/portal/login
cas.validate.url=https://xyb:8443/cas-web/proxyvalidate
如果沒在liferay下,隻是普通的web程式可用filter來實作
<filter>
<filter-name>casfilter</filter-name>
<filter-class>edu.yale.its.tp.cas.client.filter.casfilter</filter-class>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.loginurl</param-name>
<param-value>https://xyb:8443/cas-web/login</param-value>
</init-param><!--這裡的xyb是cas服務端的ip或機器名-->
<param-name>edu.yale.its.tp.cas.client.filter.validateurl</param-name>
<param-value>https://xyb:8443/cas-web/proxyvalidate</param-value>
</init-param>
<param-name>edu.yale.its.tp.cas.client.filter.servername</param-name>
<param-value>localhost:8080</param-value><!--client:port就是需要cas需要攔截的位址和端口,一般就是這個tomcat所啟動的ip和port-->
</filter>
<filter-mapping>
<url-pattern>/*</url-pattern><!--這裡就是你要攔截的url請求-->
</filter-mapping>
最後一步,在用戶端擷取cas認證通過的使用者名
1、在jsp或servlet中的用法:
<%@ page import="edu.yale.its.tp.cas.client.filter.casfilter" %>
<%@ page import="javax.servlet.http.httpservletrequest" %>
<%@ page import="javax.servlet.http.httpsession" %>
<%
httpsession ses = request.getsession();
string screenname =
(string)ses.getattribute(casfilter.cas_filter_user);
system.out.println("screenname==:"+screenname);
%>
2、在java中通過 session 擷取登入使用者名
// 以下兩者都可以
session.getattribute(casfilter.cas_filter_user);
session.getattribute("edu.yale.its.tp.cas.client.filter.user");
3、在 jstl 中擷取使用者名的方法
<c:out value="${sessionscope[cas:'edu.yale.its.tp.cas.client.filter.user']}"/>
問題彙總:
嚴重: edu.yale.its.tp.cas.client.casauthenticationexception: unable to validate proxyticketvalidator [[edu.yale.its.tp.cas.client.proxyticketvalidator prox
ylist=[null] [edu.yale.its.tp.cas.client.serviceticketvalidator casvalidateurl=[https://192.168.1.111:8443/cas/proxyvalidate] ticket=[st-0-9h7mx5hk3pfsdxrv
md3y] service=[http%3a%2f%2f192.168.1.222%3a8080%2fservlets-examples%2fservlet%2fhelloworldexample] renew=false]]]
這個cas異常是從cas client裡面抛出,是當我們不使用證書的cn去通路域名的時候(比如下文是用ip通路而且證書的cn是該ip對應的域名而非該ip),casclient無法信任,也就是我上面特意提到的那個cn的問題。要特别注意。
info [org.jasig.cas.authentication.authenticationmanager
impl] - <authenticationhandler: cn.com.tiansky.cas.authenticationhandlers.upauthenticationhandler successfully authenticated the user which provided the followi
ng credentials: [username: test]>
就種錯誤,可能是用戶端的那個配置檔案裡寫的不太對。也就是上面說的第五步,要多注意一下。
java.io.ioexception: cannot recover key
at org.apache.tomcat.util.net.jsse.jsse14socketfactory.init(jsse14socket
factory.java:125)
at org.apache.tomcat.util.net.jsse.jssesocketfactory.createsocket(jsseso
cketfactory.java:88)
at org.apache.tomcat.util.net.pooltcpendpoint.initendpoint(pooltcpendpoi
nt.java:292)
at org.apache.coyote.http11.http11baseprotocol.init(http11baseprotocol.j
ava:138)
at org.apache.catalina.connector.connector.initialize(connector.java:101
這種錯誤,可能是你生成的證書有問題,如果keypass和storepass的密碼不一緻也會把這個錯(不知為什麼非要設成一樣的)