使用CAS在Tomcat中開發統一使用者管理系統
與別的公司對接開發單點系統的客戶端,領導講最好我們也開發一套單點登入系統,於是自己研究了幾天,也使用CAS開發了一套單點當了系統,記錄步驟如下,以備以後參考:
一、服務端
1、下載cas,並配置成完整專案
在Download CAS Server欄目下點選對應版本的zip即可下載,我下載的是cas-server-3.4.8
解壓檔案將modules下的cas-server-webapp-3.4.8.war為cas.war,拷貝到tomcat6下執行後,得到cas專案
把cas-server-webapp\src\main\java的類檔案下拷貝到cas專案src裡,然後把cas專案下的class檔案裡除了編譯過的類以外全部拷貝到src裡,這樣就得到了cas整個專案。
2、驗證使用者及密碼
把cas-server-support-jdbc-3.4.8.jar和ojdbc14.jar拷貝到lib下
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
public final class CasDaoAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler
{
public CasDaoAuthenticationHandler()
{
}
public boolean authenticateUsernamePasswordInternal(UsernamePasswordCredentials credentials)
{
boolean bool = false;
String username = credentials.getUsername();
String password = credentials.getPassword();
System.out.println("開始CAS認證......");
System.out.println("userName:"+username);
System.out.println("password:"+password);
String driver = "oracle.jdbc.driver.OracleDriver";
String conn_str_1 = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
Connection conn =null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(conn_str_1,"uums","pass");
String sql = "SELECT password FROM SYS_USER WHERE LOGINNAME='"+username+"' ";//AND password='"+password+"'
ResultSet res = conn.prepareStatement(sql).executeQuery();
while(res.next()){
String psword = res.getObject(1).toString();
if(psword != null && (!"".equals(psword))){
if(password.equals(DecodeUtil.Decrypt(psword))){
System.out.println("認證成功!");
bool = true;
break;
}
}
}
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
catch (SQLException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
finally{
try{
if(conn!=null)
conn.close();
}catch(Exception e){
e.printStackTrace();
}
}
if(!bool){
System.out.println("認證不成功!");
}
return bool;
}
protected void afterPropertiesSetInternal()
throws Exception
{
// super.afterPropertiesSetInternal();
}
}
3、其他配置
a.在\WEB-INF\deployerConfigContext.xml 找到 <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
p:httpClient-ref="httpClient" p:requireSecure="false"/>
引數p:requireSecure="false",是否需要安全驗證,即HTTPS,false為不採用。
b.在/spring-configuration/ticketGrantingTicketCookieGenerator.xml和warnCookieGenerator.xml 找到
<bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
p:cookieSecure="false"
p:cookieMaxAge="-1"
p:cookieName="CASTGC"
p:cookiePath="/cas" />
p:cookieSecure 為true 為採用https,false 為http,p:cookieSecure="true" 表示只能https請求才能讀到cookie中的值,而http訪問時不能從cookie中取的值.
p:cookieMaxAge 為-1 設定瀏覽器cookie保留時間 -1為瀏覽器關閉後失效,簡單說是COOKIE的最大生命週期,-1為無生命週期,即只在當前開啟的IE視窗有效,IE關閉或重新開啟其它視窗,仍會要求驗證。
4、為了資訊傳輸將更加安全可以給tomcat配置https,SSL認證分雙向認證和單向認證,如果為雙向認證則客戶端也需要安裝已生成好的檔案
1).雙向認證配置步驟
第一次配置成功後,第二次在配置,始終不成功,中間沒有出現錯誤,但是專案不能訪問,還不知道什麼原因,懷疑是證書衝突造成的,待以後查原因。
a.、生成伺服器端證書
keytool -genkey -keyalg RSA -dname "cn=localhost,ou=sango,o=none,l=china,st=beijing,c=cn" -alias server -keypass password -keystore d:\h
ttps\server.jks -storepass password -validity 3650
說明:
keytool :是個金鑰和證書管理工具,
-genkey:命令向某個尚不存在的金鑰倉庫新增資料時,就建立了一個金鑰倉庫
-keyalg :指定了用於生成金鑰對的演算法
RSA:公鑰加密演算法
-dname:指定證書擁有者資訊,cn為要訪問的域名或ip地址
“d:\https\server.jks”:含義是將證書檔案的儲存路徑,證書檔名稱是server.jks
“-validity 3650”:含義是證書有效期,3650表示10年,預設值是90天 “
-keypass:設定密碼為password
b、生產客戶端證書
keytool -genkey -keyalg RSA -dname "cn=sango,ou=sango,o=none,l=china,st=beijing,c=cn" -alias custom -storetype PKCS12 -keypass password -keystore d:\https\custom.p12 -storepass password -validity 3650
說明:
客戶端的CN可以是任意值
-alias:產生別名,每個keystore都關聯這一個獨一無二的alias,這個alias通常不區分大小寫
-storepass 指定金鑰庫的密碼(獲取keystore資訊所需的密碼)
c、由於是雙向SSL認證,伺服器必須要信任客戶端證書,因此,必須把客戶端證書新增為伺服器的信任認證。由於不能直接將PKCS12格式的證書 庫匯入,我們必須先把客戶端證書匯出為一個單獨的CER檔案,使用如下命令,先把客戶端證書匯出為一個單獨的cer檔案:
keytool -export -alias custom -file d:\https\custom.cer -keystore d:\https\custom.p12 -storepass password -storetype PKCS12 -rfc
然後,新增客戶端證書到伺服器中(將已簽名數字證書匯入金鑰庫)
keytool -import -v -alias custom -file d:\https\custom.cer -keystore d:\https\server.jks -storepass password
d、檢視證書
keytool -list -v -keystore d:\https\server.jks -storepass password
e、配置tomcat service.xml檔案
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="D:\https\tomcat.keystore" keystorePass="password"
truststoreFile="D:\https\tomcat.keystore" truststorePass="password" />
說明:
protocol="org.apache.coyote.http11.Http11NioProtocol" :這樣配置提供tomcat的響應速度
2)tomcat6配置單向認證 (未驗證)
a、keytool -genkey -keyalg RSA -dname "cn=localhost,ou=sango,o=none,l=china,st=beijing,c=cn"
-alias server -keypass password -keystore d:\server.jks -storepass password -validity 3650
2、由於是單向認證,沒有必要生成客戶端的證書,直接進入配置tomcat service.xml檔案,Xml程式碼
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="D:/server.jks" keystorePass="password"/>
clientAuth="false"表示單向認證,同時去掉truststoreFile="D:/server.jks" truststorePass="password"這2個屬性
二、客戶端
2、編寫過濾器類
a.ClientFilter
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.jasig.cas.client.authentication.AttributePrincipal;
public class ClientFilter implements Filter {
String serviceUrl;
String appName;
String setSessionClass;
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
AttributePrincipal principal = (AttributePrincipal) ((HttpServletRequest) request).getUserPrincipal();
HttpSession session = ((HttpServletRequest) request).getSession();
String userAccount = null;
if (session.getAttribute("cas_username") == null && principal != null && principal.getName() != null ) {
//具體專案有不同的情形:
//1、所有的應用系統賬號一致
//2、所有的應用系統賬號不一致
/*1、若ezIDS的使用者賬號與第三方應用系統賬號一致*/
userAccount = principal.getName();
/*若ezIDS的使用者賬號與第三方應用系統賬號一致*/
if(userAccount == null) {
session.invalidate();
}else{
if(setSessionClass != null){
try {
SetLoginSession sls = (SetLoginSession) Class.forName(setSessionClass).newInstance();
sls.setSession(userAccount, (HttpServletRequest) request);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
session.setAttribute("cas_username", principal.getName());
}
}
chain.doFilter(request, response);
}
public void init(FilterConfig arg0) throws ServletException {
setSessionClass = arg0.getInitParameter("setSessionClass");
}
}
b.SetLoginSession
import javax.servlet.http.HttpServletRequest;
public interface SetLoginSession {
public void setSession(String username, HttpServletRequest request);
public boolean isLogined(HttpServletRequest request);
}
c.YcyySetLoginSession
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import modules.sys.Sys_user;
import modules.sys.Sys_userCtl;
public class YcyySetLoginSession implements SetLoginSession {
public void setSession(String username, HttpServletRequest request) {
request.getSession().setAttribute("org.apache.struts.action.LOCALE", Locale.CHINA);
HttpSession session = request.getSession();
Sys_user user = new Sys_userCtl().logon(username,request.getRemoteAddr());
session.setAttribute("userSession", user);
}
public boolean isLogined(HttpServletRequest request) {
return request.getSession().getAttribute("userSession") != null;
}
}
3、配置web.xml
<!--單點登入相關配置開始-->
<!-- 使用者的身份認證 -->
<filter>
<filter-name>CASFilter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name> <!-- 59.203.198.2:7080 192.168.0.149:8080-->
<param-value>http://192.168.0.149:8080/cas/login</param-value>
</init-param>
<init-param>
<param-name>renew</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>gateway</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://192.168.0.149:8080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CASFilter</filter-name>
<url-pattern>/private/index.xp</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>http://192.168.0.149:8080/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://192.168.0.149:8080</param-value>
</init-param>
<init-param>
<param-name>useSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>redirectAfterValidation</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/private/index.xp</url-pattern>
</filter-mapping>
<!-- 負責Ticket的校驗 -->
<!--該過濾器負責實現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>/private/index.xp</url-pattern>
</filter-mapping>
<!--該過濾器負責實現HttpServletRequest請求的包裹,比如允許開發者通過HttpServletRequest的getRemoteUser()方法獲得SSO登入使用者的登入名-->
<!--該過濾器使得開發者可以通過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>/private/index.xp</url-pattern>
</filter-mapping>
<!--該過濾器使得開發者可以通過org.jasig.cas.client.util.AssertionHolder來獲取使用者的登入名。比如AssertionHolder.getAssertion().getPrincipal().getName()-->
<!--YCYY設定session使用的過濾器-->
<filter>
<filter-name>setnameFilter</filter-name>
<filter-class>modules.com.casFilter.ClientFilter</filter-class>
<init-param>
<param-name>setSessionClass</param-name>
<param-value>modules.com.casFilter.YcyySetLoginSession</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>setnameFilter</filter-name>
<url-pattern>/private/index.xp</url-pattern>
</filter-mapping>
<!--YCYY設定session使用的過濾器-->
<!--單點登入相關配置結束-->
</web-app>
三、遇到的問題
1、在請求伺服器端時,會很慢,那是因為在top.jsp加了引用到https://ajax.googleapis.com網站的jquery,但是該網站不能進行訪問了,所以會很慢,去掉後就可以了。
相關推薦
使用CAS在Tomcat中開發統一使用者管理系統
與別的公司對接開發單點系統的客戶端,領導講最好我們也開發一套單點登入系統,於是自己研究了幾天,也使用CAS開發了一套單點當了系統,記錄步驟如下,以備以後參考: 一、服務端 1、下載cas,並配置成完整專案 在Download CAS Server欄目下點選對應版本的zip
跟大家推薦一個我們自己開發的任務管理系統,我們自己已使用多年,並且在不斷完善
管理 分享圖片 賬號 體驗 你們 軟件開發項目 取消 qq截圖 png 從2012年開始帶項目,當時就自己開發了一個非常簡單的任務管理系統(幾乎只有一個頁面),雖然非常簡單,但是比那些大名鼎鼎的項目管理系統更適合我們軟件開發的項目。 從2012年至今,我們自己開發的
持幣生息系統開發,會員管理系統開發,貴州雲挖礦錢包系統開發
發的 架構 原理 進一步 開發技術 開發 工作 聊天 手機 持幣生息系統開發,會員管理系統開發,貴州雲挖礦錢包系統開發數字資產交易所開發,區塊鏈多幣種錢包開發,手機錢包開發,數字資產幣幣撮合交易平臺開發,場外OTC交易系統開發C2C交易網站開發,區塊鏈聊天社交直播系統開發,
基於struts2框架開發的學生管理系統
vpd peid esc png 頁面 介紹 pass 面數據 分享 學生管理系統采用struts2框架作為後臺開發框架,jsp實現頁面數據的展示,數據庫采用mysql。功能介紹:包含學生信息管理,班級信息管理,年級信息管理,系統信息管理等功能。數據庫模型設置如下:CREA
原 Java開發企業級許可權管理系統 百度雲盤
推薦 Spring Boot/Cloud /Redis視訊: Java 微服務實踐 - Spring Boot Java 微服務實踐 - Spring Cloud redis高可用視訊 Spring原理解析視訊教程 首先先介紹一下spring secu
適合中職學生學生管理系統的研發(java+jdbc+mysql)(三)
登陸成功之後顯示新增和查詢的操作,這裡面新增的操作,是實現了監聽之後重新的新增的方法,與LoginActivity實現分離,這裡面AddLayout做新增的介面和資料庫新增的操作 public class ActionListenerImp implements java.awt.even
適合中職學生學生管理系統的研發(java+jdbc+mysql)(二)
上一章節我們說到了登陸介面的操作,只有介面,接下來要實現一個承載登陸介面的Activity.這裡面有一個IO流的操作,把賬號和密碼儲存到本地 因為登陸介面LoginLayout與LoginActivity用的介面回撥實現的介面的分離,所有我們LoginActivity裡面要Stude
適合中職學生學生管理系統的研發(java+jdbc+mysql)(一)
中職學生從學生主動性來講幾乎沒有,基礎差,在學習java的過程中,大部分學生是懶作的.所有研發一套適合中職學生的管理系統. 首先登陸介面此係統所有的介面都是用java的swing寫的 這裡面因為登陸與登陸邏輯相分離(採用的是介面回撥,這個是難點,多型知識一定要紮實,否則理解上可能
適合中職學生學生管理系統的研發(java+jdbc+mysql)(四)
這一長比較重要設計的到資料庫,我們上三的時候說到介面新增按鈕之後進入介面新增的操作,我這裡對JDBC進行了封裝,當然連線JDBC有很多的技術,我們這裡採用的properties方式,這種方式方便開發者管理,並且對初學者來說容易操作. driver=com.mysql.jdbc.Driver ur
【C語言開發】通訊錄管理系統
#include <stdio.h> #include <malloc.h> //得到指向大小為Size的記憶體區域的首位元組的指標// #include <string.h> #include <stdlib.h> //
React開發企業級後臺管理系統(筆記一環境配置)
主要介紹安裝node環境和react環境依賴安裝 node環境安裝 1,官網下載node安裝包。安裝完成後可以通過以下命令查詢安裝版本號 node -v ,只要安裝成功便會自動安裝npm 依賴包管理工
基於Koa開發學生導師管理系統
本系統的所有功能已經實現,所有程式碼開放在Github,文件和教程將會在暑假裡詳細補充完整 專案架構: EJS + Bootstrap4 實現前端頁面 Node.js + Koa2 + MySQL + Redis 實現後端服務 在軟體過程/架構的大作業中用到了E
替代crontab,任務計劃統一集中管理系統cronsun簡介
一、背景 crontab 是 Linux 系統裡面最簡單易用的定時任務管理工具,相信絕大多數開發和運維都用到過。在咱們公司,很多業務系統的定時任務都是通過 crontab 來定義的,時間長了後會發現存在很多問題: 大量的 crontab 任務散佈在各臺伺服
web開發學生資訊管理系統
開發前需要的工具要準備好,我使用的是myeclipse來做的開發,也可以使用eclipse,但需要安裝外掛,伺服器使用Tomcat7.0,資料庫使用mysql,資料庫圖形化介面使用navicat,開發中需要的jar包如下:struts的一些核心jar包(可以到str
整合SpringMVC框架+Mybatis框架開發人力資源管理系統(十)
實現使用者管理中的查詢功能並將之呈現 系統的使用者管理功能包含使用者查詢、使用者新增、使用者刪除與使用者修改等功能。 先貼上該方法程式碼: @RequestMapping(value="/selectUser") public String selectUser(
整合SpringMVC框架+Mybatis框架開發人力資源管理系統(九)
使用者登入功能的實現 由於系統設定了一個interceptor對使用者訪問進行了攔截,未登入使用者無法進入系統進行下一步的操作,因此要想實現進一步操作就必須進行登入,系統的登入功能的實現大致是:1、使用者提交登入表格引數(該請求不受攔截器攔截,可提交到前端控制器)2、前端控制器接收到該請
整合SpringMVC框架+Mybatis框架開發人力資源管理系統(八)
系統UI介面設計 為了實現許可權控制並提高安全性,我將所有的jsp頁面均放在WEB-INF的資料夾下,利用一個攔截器判斷使用者是否登入,未登入使用者不具備訪問的資格。攔截器程式碼如下: package org.fkit.hrm.interceptor; import javax.s
整合SpringMVC框架+Mybatis框架開發人力資源管理系統(七)
實現業務邏輯介面HrmService 業務邏輯介面HrmService中定義了系統功能實現所需要呼叫的方法,HrmServiceImpl類實現了該介面,對每個方法的方法體進行了具體實現: package org.fkit.hrm.impl; import java.util.Has
整合SpringMVC框架+Mybatis框架開發人力資源管理系統(六)
業務邏輯元件HrmService介面的實現 業務邏輯元件的實現需要依賴於DAO元件,在HrmService介面中針對需要操作的六個實體(User、Employee、Job、Dept、Notice、Document)設計了不一樣的業務方法(CRUD),每個方法又會呼叫DAO元件中的一個或多
整合SpringMVC框架+Mybatis框架開發人力資源管理系統(五)
部署DAO層 對前面實現的DAO元件的呼叫有兩種方式實現: 一是通過SqlSession物件的getMapper()方法獲取介面例項,程式碼如下: try( InputStream is=Resources.getRessourceAsStream("mybatis-conf