1. 程式人生 > >使用CAS在Tomcat中開發統一使用者管理系統

使用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

keytool -genkey -keyalg RSA -dname "cn=localhost,ou=sango,o=none,l=china,st=beijing,c=cn" -alias server -keypass password -keystore 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