1

一些芝士

SSO的技术的几种技术方案

  • 基于cookies实现

适合同父域(将domain设置为rebey.cn,则a.rebey.cn与b.rebey.cn共享cookie)

  • 基于session共享来实现

Session中所涉及的类型必须是子系统中共同拥有的(即程序集、类型都需要一致),不同语言互通相对麻烦

  • 基于票据ticket来实现(CAS)

支持跨域,支持多语言客户端

请求过程

pac4j

image

图一来自pac4j,图二来自网络(哪篇博客存的图在下忘了- -)。很透彻的两张图。

image

图三为本人手绘。描述了先访问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单点登录


花田土著
190 声望34 粉丝

希望加入有意思的开发团队!