1. 程式人生 > >02單點登入CAS5.3.4資料庫JDBC認證

02單點登入CAS5.3.4資料庫JDBC認證

上一章搭建了單點登入的基本搭建,但是它的使用者名稱和密碼是寫死的。顯然,這樣是不行的,使用者名稱密碼一般都存放在資料庫中。本文將介紹如何讓CAS支援MySQL儲存使用者名稱和密碼。

1.初始化MySQL使用者表

CREATE TABLE `sys_user` (
 `username` varchar(20) NOT NULL,
 `password` varchar(36) NOT NULL,
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `nickname` varchar(20) NOT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `username_` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

/*Data for the table `sys_user` */

insert  into `sys_user`(`username`,`password`,`id`,`nickname`) values ('admin','password',1,'admin');

2.新增pom依賴

<dependency>
   <groupId>org.apereo.cas</groupId>
   <artifactId>cas-server-support-jdbc</artifactId>
   <version>${cas.version}</version>
</dependency>
<dependency>
   <groupId>org.apereo.cas</groupId>
   <artifactId>cas-server-support-jdbc-drivers</artifactId>
   <version>${cas.version}</version>
</dependency>
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.36</version>
</dependency>

3.新增資料庫配置


##
# CAS Authentication Credentials  預設的靜態使用者名稱和密碼配置
# 註釋預設賬號密碼
#cas.authn.accept.users=casuser::Mellon

#新增jdbc認證
cas.authn.jdbc.query[0].sql=SELECT * FROM sys_user WHERE username =?
#哪一個欄位作為密碼欄位
cas.authn.jdbc.query[0].fieldPassword=password
#配置資料庫連線
cas.authn.jdbc.query[0].url=jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect
#資料庫使用者名稱
cas.authn.jdbc.query[0].user=root
#資料庫密碼
cas.authn.jdbc.query[0].password=123456
#mysql驅動
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver

4.啟動idea登入cas

image

現在資料庫中的密碼是明文儲存的,一般資料庫中的密碼是MD5加密後再儲存的,所以需要對密碼進行處理

5.配置MD5加密

#登入密碼配置加密策略
cas.authn.jdbc.query[0].passwordEncoder.type=DEFAULT
cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8
cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD5

啟動後用admin password登入提示認證資訊無效。插入一條新的資料庫記錄 image

insert  into `sys_user`(`username`,`password`,`id`,`nickname`) values ('zhangsan','5f4dcc3b5aa765d61d8327deb882cf99',2,'張三');

image

6.對密碼進行鹽值處理

步驟5只是對密碼進行了簡單的加密,推薦使用鹽值 修改application.properties,在上面的基礎上,再新增如下程式碼,可以共存

#2.對登入密碼鹽值處理。如果兩種方式都配置的話,預設先用普通MD5驗證,如果驗證失敗,列印異常日誌,然後再使用加鹽方式驗證。
#加密迭代次數
cas.authn.jdbc.encode[0].numberOfIterations=2
#該列名的值可替代上面的值,但對密碼加密時必須取該值進行處理
cas.authn.jdbc.encode[0].numberOfIterationsFieldName=
#鹽值固定列
cas.authn.jdbc.encode[0].saltFieldName=username
#靜態鹽值
cas.authn.jdbc.encode[0].staticSalt=.
cas.authn.jdbc.encode[0].sql=SELECT * FROM sys_user WHERE username =?
#對處理鹽值後的演算法
cas.authn.jdbc.encode[0].algorithmName=MD5
cas.authn.jdbc.encode[0].passwordFieldName=password
cas.authn.jdbc.encode[0].expiredFieldName=expired
cas.authn.jdbc.encode[0].disabledFieldName=disabled
#資料庫連線
cas.authn.jdbc.encode[0].url=jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
cas.authn.jdbc.encode[0].dialect=org.hibernate.dialect.MySQL5Dialect
cas.authn.jdbc.encode[0].driverClass=com.mysql.jdbc.Driver
cas.authn.jdbc.encode[0].user=root
cas.authn.jdbc.encode[0].password=123456

利用下面的幫助類生成鹽值

package com.weisi.veems.frame.utils;

import org.apache.shiro.crypto.hash.ConfigurableHashService;
import org.apache.shiro.crypto.hash.DefaultHashService;
import org.apache.shiro.crypto.hash.HashRequest;
import org.apache.shiro.util.ByteSource;

/**
 * @author:luomouren
 * @description:
 * @dateTime: created in  2018-10-31 14:50
 * @modified by:
 **/
public class PasswordSalt {
	/**
	 * 靜態鹽值
	 */
	private static final String STATIC_SALT = ".";
	/**
	 * 對處理鹽值後的演算法
	 */
	private static final  String ALGORITHM_NAME = "MD5";

	/**
	 * 對登入密碼鹽值處理
	 * @param username 賬號
	 * @param password 密碼
	 * @throws Exception
	 */
	public static String encryPassword(String username,String password) throws Exception {
		ConfigurableHashService hashService = new DefaultHashService();
		// 靜態鹽值
		hashService.setPrivateSalt(ByteSource.Util.bytes(STATIC_SALT));
		hashService.setHashAlgorithmName(ALGORITHM_NAME);
		// 加密迭代次數
		hashService.setHashIterations(2);
		HashRequest request = new HashRequest.Builder()
				.setSalt(username)
				.setSource(password)
				.build();
		String res =  hashService.computeHash(request).toHex();
		System.out.println(res);
		return  res;
	}

	public static void main(String[] args) {
		try {
			PasswordSalt.encryPassword("lisi","password");
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

往資料庫中插入記錄

insert  into `sys_user`(`username`,`password`,`id`,`nickname`) values ('lisi','d8ab2b68f1a4af359e86928302585826',3,'李四');

利用zhangsan password 和 lisi password登入驗證成功