一些芝士
SSO的技术的几种技术方案
- 基于cookies实现
适合同父域(将domain设置为rebey.cn,则a.rebey.cn与b.rebey.cn共享cookie)
- 基于session共享来实现
Session中所涉及的类型必须是子系统中共同拥有的(即程序集、类型都需要一致),不同语言互通相对麻烦
- 基于票据ticket来实现(CAS)
支持跨域,支持多语言客户端
请求过程
图一来自pac4j,图二来自网络(哪篇博客存的图在下忘了- -)。很透彻的两张图。
图三为本人手绘。描述了先访问A系统再访问B系统。记录下过程中一些重要点和问题:
一直纠结4认证成功后为什么要进行5,6步。暂且理解为为了解决跨域问题。
初始构建
从cas-management-overlay下载官方提供的maven overlay(省去下载源码通过gradle去构建环节)。
根据实际情况调整pom.xml;如:依赖的war包通过ali库无法下载,需要手动下载。
cmd运行build.cmd run启动(前提是需要安装maven,配置环境变量)。这种启动方式不太友好,是否能直接通关eclipse启动希望赐教。
启动后默认地址:http://localhost:8443/cas
默认用户名/密码为:casuser/Mellon
修改为oracle数据库jdbc验证
#cas.authn.accept.users=casuser::Mellon
cas.authn.jdbc.query[0].sql=select password from cap_user where user_id=?
cas.authn.jdbc.query[0].healthQuery=SELECT 1 from dual
cas.authn.jdbc.query[0].isolateInternalQueries=false
cas.authn.jdbc.query[0].url=jdbc:oracle:thin:@127.0.0.1:1521/ORCL
cas.authn.jdbc.query[0].failFast=true
cas.authn.jdbc.query[0].isolationLevelName=ISOLATION_READ_COMMITTED
cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.OracleDialect
cas.authn.jdbc.query[0].leakThreshold=10
cas.authn.jdbc.query[0].propagationBehaviorName=PROPAGATION_REQUIRED
cas.authn.jdbc.query[0].batchSize=1
cas.authn.jdbc.query[0].user=iamsuser
cas.authn.jdbc.query[0].ddlAuto=create-drop
cas.authn.jdbc.query[0].maxAgeDays=180
cas.authn.jdbc.query[0].password=iamsuser
cas.authn.jdbc.query[0].autocommit=false
cas.authn.jdbc.query[0].driverClass=oracle.jdbc.driver.OracleDriver
cas.authn.jdbc.query[0].idleTimeout=5000
cas.authn.jdbc.query[0].fieldPassword=password
自定义加密匹配
cas.authn.jdbc.query[0].passwordEncoder.type= com.che.ChePasswordEncoder
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import sun.misc.BASE64Encoder;
public class ChePasswordEncoder implements PasswordEncoder {
// 盐值(加密混淆)
private final static String slat = "diasj29er2ur734tuei89u34efdfi30q7u5834tdphf056=-251758";
/**
* 利用MD5进行加密
*
* @param str 待加密的字符串
* @return 加密后的字符串
* @throws NoSuchAlgorithmException 没有这种产生消息摘要的算法
* @throws UnsupportedEncodingException
*/
@Override
public String encode(CharSequence rawPassword) {
if (rawPassword == null) {
return null;
}
String newstr = null;
rawPassword = rawPassword + "/" + slat;
// 确定计算方法
MessageDigest md5;
try {
md5 = MessageDigest.getInstance("MD5");
BASE64Encoder base64en = new BASE64Encoder();
// 加密后的字符串
newstr = base64en.encode(md5.digest(rawPassword.toString().getBytes("utf-8")));
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
System.out.println("==========================="+newstr);
return newstr;
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
String encodeedRawPassword = StringUtils.isNotBlank(rawPassword) ? this.encode(rawPassword.toString()) : null;
boolean matched = StringUtils.equals(encodeedRawPassword, encodedPassword);
return matched;
}
}
可返回(用户表)更多属性配置
cas.authn.attributeRepository.jdbc[0].singleRow=true
cas.authn.attributeRepository.jdbc[0].order=0
cas.authn.attributeRepository.jdbc[0].url=jdbc:oracle:thin:@127.0.0.1:1521/ORCL
cas.authn.attributeRepository.jdbc[0].username=user_id
cas.authn.attributeRepository.jdbc[0].user=iamsuser
cas.authn.attributeRepository.jdbc[0].password=iamsuser
cas.authn.attributeRepository.jdbc[0].sql=select * from cap_user where user_id=?
cas.authn.attributeRepository.jdbc[0].dialect=org.hibernate.dialect.OracleDialect
cas.authn.attributeRepository.jdbc[0].ddlAuto=none
cas.authn.attributeRepository.jdbc[0].driverClass=oracle.jdbc.driver.OracleDriver
cas.authn.attributeRepository.jdbc[0].leakThreshold=10
cas.authn.attributeRepository.jdbc[0].propagationBehaviorName=PROPAGATION_REQUIRED
cas.authn.attributeRepository.jdbc[0].batchSize=1
cas.authn.attributeRepository.jdbc[0].healthQuery=SELECT 1 from dual
cas.authn.attributeRepository.jdbc[0].failFast=true
这里很多相同的参数配置两遍应该不太友好的,有待推敲;
jdbc[0]这种 转 yml格式搜不到可行写法,希望有缘人赐教。
不允许使用CAS来认证您访问的目标应用。
src/main/resources下添加services文件夹,添加HTTPSandIMAPS-10000001.json(文件名有规则,暂时未知):
{
"@class": "org.apereo.cas.services.RegexRegisteredService",
"serviceId": "^(http|https|imaps)://.*",
"name": "HTTPS and IMAPS",
"id": 10000001,
"description": "This service definition authorizes all application urls that support HTTPS and IMAPS protocols.",
"evaluationOrder": 10000,
"attributeReleasePolicy": {
"@class": "org.apereo.cas.services.ReturnAllAttributeReleasePolicy"
}
}
啰嗦几句
本意springboot+shiro集成cas,需要一个cas server,发现相关资料很少,尤其中文好资料。因为大公司都用自己的开发的cas吗。。
待续...
更多有意思的内容,欢迎访问笔者小站: rebey.cn
一些链接
本文github:点这里;
官方软文:cas5-gettingstarted-overlay;
@yuchanghui搭建的server与client:buyi-sso;
系列博客:CAS单点登录;
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。