CAS項目官網 是一款開源的單點登陸解決方案,能夠直接再Tomcat,Jetty等WEB容器上運行,支持多種開發語言css
下載cas-server-XXX-release.zip(地址)html
注意:官網提供的全部版本中,最新的版本(4.0以上)可能沒有release.zip包java
生成keypair mysql
在 $JRE_HOME/bin/
目錄下建立命令行,輸入如下命令,其中CN
的值必須保持和主機名一致,假設密碼爲 mypass
,再繼續填寫信息,遇到主密碼直接回車web
keytool -genkeypair -alias cas -keyalg RSA -storepass mypass
上述命令會在用戶目錄下生成一個.keystore文件,後面會使用該文件其餘的幾個經常使用命令spring
# 查看 keypair:
keytool -list -storepass mypass
# 刪除 keypair:keytool -delete -alias <別名> -storepass mypass
sql
導出證書 數據庫
keytool -exportcert -alias cas -file cas.crt -storepass mypass
上述命令會在當前目錄生成一個cas.crt證書文件,後面也會使用該文件apache
向JVM導入證書 windows
keytool -importcert -alias cas -file cas.crt -keystore "%JAVA_HOME%\jre\lib\security\cacerts" -storepass mypass -noprompt
上面的JAVA_HOME
須要換成實際的路徑
修改配置文件
不一樣版本的cas對jdk版本的要求不同,請查閱cas說明
修改tomcat目錄下的conf/server.xml,打開SSL
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="off" /> 配置HTTPS端口 <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="apache-tomcat-7.0.73\conf\security\.keystore" keystorePass="mypass"/>
若是要確保訪問HTTPS服務只能用8443端口,則須要禁用其餘端口號
訪問cas服務
重啓tomcat: 在 tomcat/bin/
下先執行 shutdown
,再執行 startup
。訪問cas的地址爲 https://localhost:8443/cas/login
WEB集成CAS-CLIENT
在Spring服務的pom.xml
加入cas-client的依賴包
<!--cas client--> <dependency> <groupId>org.jasig.cas.client</groupId> <artifactId>cas-client-core</artifactId> <version>3.3.3</version> </dependency>
在Spring的項目配置文件web.xml
中加入cas的配置
<!-- ======================== 單點登陸開始 ======================== --> <listener> <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class> </listener> <!-- 該過濾器用於實現單點登出功能,可選配置。 --> <filter> <filter-name>CAS Single Sign Out Filter</filter-name> <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class> </filter> <filter-mapping> <filter-name>CAS Single Sign Out Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>CAS Filter</filter-name> <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class> <init-param> <param-name>casServerLoginUrl</param-name> <param-value>https://nkgy4l003835331:8443/cas/login</param-value> <!-- 這裏只能使用主機名的url --> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://localhost:8080</param-value> </init-param> </filter> <filter-mapping> <filter-name>CAS Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 該過濾器負責對Ticket的校驗工做,必須啓用它 --> <filter> <filter-name>CAS Validation Filter</filter-name> <filter-class> org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class> <init-param> <param-name>casServerUrlPrefix</param-name> <param-value>https://nkgy4l003835331:8443/cas</param-value> <!-- 這裏只能使用主機名的url --> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://localhost:8080</param-value> </init-param> </filter> <filter-mapping> <filter-name>CAS Validation Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 該過濾器負責實現HttpServletRequest請求的包裹, 好比容許開發者經過HttpServletRequest的getRemoteUser()方法得到SSO登陸用戶的登陸名,可選配置。 --> <filter> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <filter-class> org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class> </filter> <filter-mapping> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 該過濾器使得開發者能夠經過org.jasig.cas.client.util.AssertionHolder來獲取用戶的登陸名。 好比AssertionHolder.getAssertion().getPrincipal().getName()。 --> <filter> <filter-name>CAS Assertion Thread Local Filter</filter-name> <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class> </filter> <filter-mapping> <filter-name>CAS Assertion Thread Local Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- ======================== 單點登陸結束 ======================== -->
同一個Tomcat下部署CAS-Server和Spring Web須要在tomcat的server.xml
中建立兩個Service
<!-- 用於HTTP應用 --> <Service name="Catalina"> </Service> <!-- 用於CAS的HTTPS應用 --> <Service name="Catalina.cas"> </Service>
將HTTPS的移動到Catalina.cas中,並配置context的path路徑cas的包路徑
<Service name="Catalina.cas"> <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="F:\software\apache-tomcat-7.0.73-windows-x64\apache-tomcat-7.0.73\conf\security\keystore.jks" keystorePass="changeit"/> <Engine name="Catalina.cas" defaultHost="localhost"> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="false" deployOnStartup="false"> <Context path="/cas" docBase="cas" reloadable="false" />
配置HTTP的context
與上一步相似,context的path填WEB項目的地址
CAS鏈接數據庫
複製cas下載包中的 cas-server-support-jdbc-*.jar
到 tomcat/webapps/cas/WEB-INF/lib
中
複製數據庫驅動包(如 mysql-connector.jar
)到 tomcat/webapps/cas/WEB-INF/lib
中
tomcat/webapps/cas/WEB-INF/cas.properties
中加入如下數據庫的配置# == Basic database connection pool configuration == database.driverClass=com.mysql.jdbc.Driver database.url=jdbc:mysql://127.0.0.1:3306/test database.user=root database.password=root
修改 tomcat/webapps/cas/WEB-INF/deployerConfigContext.xml 配置
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" p:driverClassName="${database.driverClass}" p:url="${database.url}" p:username="${database.user}" p:password="${database.password}"> </bean>
// 如下使用cas自帶的加密類 <bean id="md5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"> <constructor-arg index="0"> <value>MD5</value> </constructor-arg> </bean>
<!-- <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" /> -->
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"> <property name="dataSource" ref="dataSource"></property> <property name="sql" value="select password from tb_user where account=?"></property> <property name="passwordEncoder" ref="md5PasswordEncoder"></property> </bean>
重啓tomcat從新登錄
CAS的登錄頁jsp文件在 tomcat/webapps/cas/WEB-INF/view/jsp/default/ui/casLoginView.jsp
修改注意事項
tomcat/webapps/cas
目錄下的位置,能夠參考 tomcat/webapps/cas/css
,引用代碼示例:<link href="/css/login.css" rel="stylesheet" type="text/css">
保持如下內容完整,由於如下內容會將值傳給login請求
<form:form method="post" id="fm1" cssClass="fm-v clearfix" commandName="${commandName}" htmlEscape="true"> <input type="hidden" name="lt" value="${loginTicket}" /> <input type="hidden" name="execution" value="${flowExecutionKey}" /> <input type="hidden" name="_eventId" value="submit" /> <form:input id="username" .../> <form:password id="password" .../>
原有的控件具備友好的功能,能夠適當考慮保留和優化,以下面是登錄失敗提示憑證錯誤的控件
<form:errors path="*" id="msg" cssClass="errors" element="div" />
保存文件,刷新瀏覽器便可
在CAS Server上添加註冊功能
CAS自己不具備註冊功能,由於CAS要開放註冊業務給其餘業務系統,CAS單一負責登錄校驗和會話管理
修改步驟
在 tomcat/webapps/cas/WEB-INF/view/jsp/default/ui/
中加入註冊頁的jsp文件,如casRegisterView.jsp
,傳入參數爲username
和password
在 tomcat/webapps/cas/WEB_INF/classes/default_views.properties
中添加註冊頁的view映射
添加註冊頁
casRegisterView.(class)=org.springframework.web.servlet.view.JstlView
casRegisterView.url=/WEB-INF/view/jsp/default/ui/casRegisterView.jsp
package x.y.z; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractController; //必須繼承AbstractController控制器基礎類 public class RegisterController extends AbstractController { private DatabaseHandler dataHandler;//數據庫處理類(bean注入) // 必須實現的方法 protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView signinView=new ModelAndView(); String username=request.getParameter("username"); String password=request.getParameter("password"); if(username == null || username.equals("") || password == null || password.equals("")){ return new ModelAndView("casRegisterView"); } boolean success = this.dataHandler.insertUser(username,password); String viewName=getSignInView(request); signinView.setViewName(viewName); return signinView; } // 處理跳轉url protected String getSignInView(HttpServletRequest request) { String service = ServletRequestUtils.getStringParameter(request, "service", ""); return ("redirect:login" + (service.length() > 0 ? "?service=" + service : "")); } // 開放設置dataHandler,用於bean注入 public void setDataHandler(DatabaseHandler handler){ this.dataHandler = handler; } }
package x.y.z; import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import javax.sql.DataSource; class DatabaseHandler{ // 數據庫操做模板類 private SimpleJdbcTemplate jdbcTemplate; // 數據源 private DataSource dataSource; // 自定義方法,示例爲插入一個新用戶 public boolean insertUser(String username,String password){ int r = 0; try { r = this.jdbcTemplate.update("insert into tb_user(account,password,time) values(?,?,?)",username,password,System.currentTimeMillis()/1000); }catch (Exception e){ e.printStackTrace(); return false; } return r > 0; } //設置datasource注入 public final void setDataSource(final DataSource dataSource) { this.jdbcTemplate = new SimpleJdbcTemplate(dataSource); this.dataSource = dataSource; } }
將3-4的兩個java文件打包成jar文件,並最終放到 tomcat/webapps/cas/WEB-INF/lib
中
# 因爲java文件中引用了其餘類,因此須要用 -cp 連接jar包 javac -cp "tomcat/webapps/cas/WEB-INF/lib/*" RegisterController.java.java javac -cp "tomcat/webapps/cas/WEB-INF/lib/*" DatabaseHandler.java.java
# 能夠將兩個文件打包在一塊兒,也能夠分開打包。例如打包在一塊兒,名字取爲my-register.jar # @注意: 因爲3-4建立的java文件包含package 值,因此用jar打包時必須將class文件放在當前目錄下的package子目錄下,例如當前目錄下的 x/y/z/目錄下 jar cvf my-register.jar x/y/z/*.class
修改 tomcat/webapps/cas/WEB-INF/cas-servlet.xml
文件配置
<bean id="dataHandler" class="com.cas.luodong.web.DatabaseHandler"> <property name="dataSource" ref="dataSource"></property> </bean>
<bean id="registerController" class="com.cas.luodong.web.RegisterController" p:dataHandler-ref="dataHandler"/>
<prop key="/register">registerController</prop> 修改 tomcat/webapps/cas/WEB-INF/web.xml 文件配置
<servlet-mapping> <servlet-name>cas</servlet-name> <url-pattern>/validate</url-pattern> </servlet-mapping>
重啓tomcat,訪問 cas/register
能夠看到結果
java.lang.IllegalArgumentException: casServerUrlPrefix cannot be null
解決辦法: cas-client-core的版本3.4.1不支持RC5,改成3.3.3便可
java.security.cert.CertificateException: No name matching localhost found
解決辦法: jdk生成證書時填寫的CN值必須爲當前主機的主機名
java.security.cert.CertificateException: No subject alternative names present
解決辦法: web.xml中的 casServerLoginUrl 和 casServerUrlPrefix 不能使用ip,必須使用CN值
CAS is Unavailable ; There was an error trying to complete your request. Please notify your support desk or try again.
解決辦法: 檢查ui下的jsp文件是否有誤,確認標籤匹配正確