国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

【SSO單點系列】(7):CAS4.0 SERVER通過數(shù)據(jù)庫方式認證用戶

2019-11-14 23:01:28
字體:
供稿:網(wǎng)友
【SSO單點系列】(7):CAS4.0 SERVER通過數(shù)據(jù)庫方式認證用戶

  在前幾篇中有簡單介紹服務(wù)端的認證方式,默認的是直接在 deployerConfigContext.xml 文件中 一個叫做 PRimaryAuthenticationHandler 的bean中配置。不過這只支持一個賬號,而且是固定的,這有非常大的局限性,在現(xiàn)實系統(tǒng)中是肯定不能用這樣的方式的。

現(xiàn)在的應(yīng)用系統(tǒng)一般都是通過讀取數(shù)據(jù)庫的方式驗證用戶名、密碼是否正確,進而進行認證的。因此在這一篇文章中將會介紹,怎么把服務(wù)端的默認認證方式改造成數(shù)據(jù)庫驗證的方式,以此滿足系統(tǒng)的基本需求。

1.增加數(shù)據(jù)源配置

數(shù)據(jù)源的配置和平常我們配置的差不多,CAS可以使用Spring方式進行配置,為了和原來的配置文件分開,我新建了一個叫做 applicationContext-datasource.xml 的配置用來存放數(shù)據(jù)源的相關(guān)配置,(放在cas-server-webapp/src/main/webapp/WEB-INF/spring-configuration下)具體如下:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:p="http://www.springframework.org/schema/p"    xmlns:aop="http://www.springframework.org/schema/aop"    xmlns:tx="http://www.springframework.org/schema/tx"    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">    <description>datasource</description>   <bean id="casDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">        <property name="url" value="${url}" />        <property name="username" value="${username}" />        <property name="passWord" value="${password}" />        <property name="driverClassName" value="${driverClassName}" />           <property name="maxActive" value="${maxActive}" />          <property name="initialSize" value="${initialSize}" />          <property name="maxWait" value="${maxWait}" />          <property name="minIdle" value="${minIdle}" />            <property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}" />          <property name="minEvictableIdleTimeMillis" value="${minEvictableIdleTimeMillis}" />            <property name="validationQuery" value="${validationQuery}" />          <property name="testWhileIdle" value="${testWhileIdle}" />          <property name="testOnBorrow" value="${testOnBorrow}" />          <property name="testOnReturn" value="${testOnReturn}" />          <property name="maxOpenPreparedStatements" value="${maxOpenPreparedStatements}" />          <property name="removeAbandoned" value="${removeAbandoned}" /> <!-- 打開removeAbandoned功能 -->          <property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}" /> <!-- 1800秒,也就是30分鐘 -->          <property name="logAbandoned" value="${logAbandoned}" /> <!-- 關(guān)閉abanded連接時輸出錯誤日志 -->      </bean>         <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="casDataSource" />         <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"          p:dataSource-ref="casDataSource" />        <!-- 通過AOP配置提供事務(wù)增強,讓AccountService下所有Bean的所有方法擁有事務(wù) -->    <aop:config>        <aop:pointcut id="serviceMethod" expression=" execution(* com.blog.cas.account.service.impl..*(..))" />        <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" />    </aop:config>    <tx:advice id="txAdvice" transaction-manager="transactionManager">        <tx:attributes>            <tx:method name="get*" propagation="REQUIRED" read-only="true"  />            <tx:method name="update*" propagation="REQUIRED" />        </tx:attributes>    </tx:advice>            <bean id="accountService" class="com.blog.cas.account.service.impl.AccountServiceImpl" p:accountDao-ref="accountDao" />    <bean id="accountDao" class="com.blog.cas.account.dao.impl.AccountDaoImpl" p:jdbcTemplate-ref="jdbcTemplate" />    </beans>

注:在這邊有定義一個Service、一個Dao ,是用來與數(shù)據(jù)庫進行交互的,里面大家寫自己需要的方法就行了。這邊使用的Spring提供的JdbcTemplate 進行查詢。這兩個類就不貼出來了,大家自由實現(xiàn)

然后數(shù)據(jù)源的相關(guān)信息,我直接放在文件 cas.properties(cas-server-webapp/src/main/webapp/WEB-INF/cas.properties), 在最后增加下面的內(nèi)容:

### Jdbcurl=jdbc:Oracle:thin:@192.168.1.101:1521:odsorclusername=blogpassword=blogdriverClassName=oracle.jdbc.driver.OracleDrivervalidationQuery=SELECT 1 from dual filters=stat  maxActive=20  initialSize=1  maxWait=60000  minIdle=10  timeBetweenEvictionRunsMillis=60000  minEvictableIdleTimeMillis=300000  testWhileIdle=true  testOnBorrow=false  testOnReturn=false  maxOpenPreparedStatements=20  removeAbandoned=true  removeAbandonedTimeout=1800  logAbandoned=true

用的是oracle數(shù)據(jù)庫。

2.自定義認證Handler類

cas 默認使用的認證類為 org.jasig.cas.authentication.AcceptUsersAuthenticationHandler。我們看看它的源碼,發(fā)現(xiàn)認證是在一個叫做 authenticateUsernamePasswordInternal 的方法中進行的,其實看方法名大家都能猜出來這個方法是做什么的。然后這個類的父類是AbstractUsernamePasswordAuthenticationHandler ,那么我們也繼承這個類,實現(xiàn)authenticateUsernamePasswordInternal方法其實就可以了。

這邊還要注意一下,authenticateUsernamePasswordInternal 方法中的參數(shù)是一個 UsernamePasswordCredential 類型的參數(shù),里面其實包含了我們在頁面上輸入的用戶相關(guān)信息,即用戶名和密碼。好了知道方法了,那么就動手吧。

public class BlogUsersAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler {    private AccountServiceImpl accountService;        @Override    protected HandlerResult authenticateUsernamePasswordInternal(            UsernamePasswordCredential credential)            throws GeneralSecurityException, PreventedException {                String username = credential.getUsername();        String password = credential.getPassword();                boolean flag = accountService.checkAccount(username, password);        if (!flag) {           throw new FailedLoginException();        }        return createHandlerResult(credential, new SimplePrincipal(username), null);    }    //省略get/set 方法    }

這邊只是一個簡單的驗證邏輯,實際上可能會復(fù)雜點,比如判斷用戶的狀態(tài)、是否禁用等等。

然后修改相關(guān)的配置,打開文件 cas-server-webapp/src/main/webapp/WEB-INF/deployerConfigContext.xml 找到 id 為 primaryPrincipalResolver 的bean ,把這個修改成我們新增的類

 <!-- <bean id="primaryAuthenticationHandler"          class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler">        <property name="users">            <map>                <entry key="admin" value="admin"/>            </map>        </property>    </bean> -->     <bean id="primaryAuthenticationHandler"          class="org.jasig.cas.authentication.BlogUsersAuthenticationHandler">          <property name="accountService" ref="accountService" />    </bean>

好了,現(xiàn)在已經(jīng)修改成通過數(shù)據(jù)庫認證的方式了,大家可以試試看。

3.認證流程

看完了上面的,大家可能會覺得有點不理解。為什么只加了一個類,覆蓋了其中的方法就完成了認證呢,在這節(jié)中介紹下大概的一個認證流程,以及到最終的信息返回給客戶端的這樣的一個流程。

其中一些內(nèi)容在第四篇中有介紹了,最好先了解下第四篇 登錄后用戶信息的返回 相關(guān)的內(nèi)容, 傳送門

  1. 用戶登錄頁輸入相關(guān)信息,點擊submit登陸
  2. 執(zhí)行AuthenticationViaFormAction 類中的 submit 方法中
  3. 在submit方法中 調(diào)用 CentralAuthenticationService 類的grantServiceTicket 方法,其中有傳入 Credential 類型的參數(shù)
  4. 接著在grantServiceTicket方法中 調(diào)用了 AuthenticationManager類(實際類為PolicyBasedAuthenticationManager)的authenticate 方法
  5. authenticate方法中又調(diào)用了authenticateInternal 方法
  6. 最終在 authenticateInternal 方法中調(diào)用了AuthenticationHandler 的authenticate 的方法 ,authenticate 方法就會調(diào)用我們上面自定義的 BlogUsersAuthenticationHandler 方法
  7. 然后根據(jù)我們寫的方法返回的相關(guān)信息調(diào)用 resolvePrincipal 方法,把credential 類型的信息轉(zhuǎn)變?yōu)镻rincipal類型的信息,即組裝我們需要返回給客戶端的一些信息。這個主要是通過 PrincipalResolver 類進行轉(zhuǎn)變得,第四篇中有重點說到,這邊就不細講了。
  8. 最終成功登陸到客戶端

上面的流程只是認證的主要流程,不包含ST的生成、驗證等過程。

4.總結(jié)

通過數(shù)據(jù)庫認證基本上寫完了,不過上面只是簡單的演示了下,大家需要根據(jù)自己的情況進行修改。

如果上面的內(nèi)容有錯誤,歡迎大家指出。也歡迎大家多多留言。大家共同進步。

順便祝大家情人節(jié)快樂新年快樂。

打完收工...


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 峨山| 清苑县| 南郑县| 沁水县| 肇源县| 平乡县| 南京市| 湟源县| 吴江市| 金山区| 鄢陵县| 榆林市| 罗田县| 鹿泉市| 博罗县| 贵溪市| 宁波市| 镶黄旗| 茶陵县| 敦煌市| 萍乡市| 栾川县| 长乐市| 彰武县| 纳雍县| 九江县| 普宁市| 夹江县| 钟山县| 鄂伦春自治旗| 青冈县| 镇巴县| 镇江市| 遵义县| 象州县| 沙坪坝区| 无锡市| 左贡县| 岚皋县| 松溪县| 朝阳区|