15 分钟部署一个 CAS 服务并对接 Shibboleth

可莉
• 阅读 510

前言

这是一个标题党。

CAS 是一个经典的单点登录方案,又有 开源版本 的支持,因此广大提供统一身份认证解决方案的供应商鲜有不支持 CAS 的——至少投标方案上是这样的。尽管如此,实际对接的时候可能会遇到问题,又或者 CAS 不归自己负责,想做个测试又不太方便接入生产环境,总之这时候就特别想要自己部署一个测试的 CAS 来进行验证。

是的,搭一个 CAS 服务器 15 分钟就够了。

注意下文部署的 CAS 仅适合测试,不要拿这个 CAS 直接用作生产环境哦。

cas-overlay

尽管 CAS 的功能极多且复杂,但是如果只考虑测试话,我们可以尽量简化他的配置。我们只引入ldapjson-service-registry 模块,并打包成 docker 以简化环境配置。

考虑到测试方便,我们把 casshibboleth-idp 安装在同一台服务器,因此使用了 httpd 来对两者进行代理。

本文假定已经安装好了 shibboleth-idp-3.4.6 ,并使用 httpd 方式代理发布。

  1. 首先拉取 apereo/cas-overlay-template ,由于 6.2.x 尚未正式发布,我切换到 6.1.x 分支。

    git clone https://github.com/apereo/cas-overlay-template.git cd cas-overlay-template/ git checkout 6.1

  2. 修改 build.gradle ,在 dependencies 内增加 ldapjson-service-registry 的编译依赖

    dependencies { // Other CAS dependencies/modules may be listed here... compile "org.apereo.cas:cas-server-support-json-service-registry:${casServerVersion}" compile "org.apereo.cas:cas-server-support-ldap:${casServerVersion}" }

  3. 安装 docker,详见 Get Docker Engine - Community for CentOS

    $ sudo yum install -y yum-utils
    device-mapper-persistent-data
    lvm2

    $ sudo yum-config-manager
    --add-repo
    https://download.docker.com/linux/centos/docker-ce.repo $ sudo yum install docker-ce docker-ce-cli containerd.io $ sudo systemctl start docker

  4. 修改 cas-overlay-template/etc/cas/config/cas.properties 配置文件。由于我们使用 httpd 代理 cas 服务,所以我们这里可以让 httpd 卸载掉 https , cas 服务运行在 http 上即可。同时加载 json 目录的服务注册配置。
    最后一行表示 cas 所释放的属性,倒数第二行表示 ldap 内属性和 cas 的映射关系。例如如果用 AD 的话,那么这里可以配成 cas.authn.ldap[0].principalAttributeList=employeeType:employeeType,sAMAccountName:uid,此时 cas 所释放的属性名依然是 uid,由 sAMAccountName 映射产生。

    server.port=8080 server.ssl.enabled=false cas.server.tomcat.http.enabled=false

    cas.server.name=https://idp.exmaple.org cas.server.prefix=${cas.server.name}/cas

    logging.config: file:/etc/cas/config/log4j2.xml

    cas.serviceRegistry.initFromJson=false cas.serviceRegistry.json.location=file:/etc/cas/services

    cas.authn.ldap[0].type=AUTHENTICATED cas.authn.ldap[0].ldapUrl=ldap://ldap.example.org:389 cas.authn.ldap[0].useSsl=false cas.authn.ldap[0].baseDn=dc=example,dc=org cas.authn.ldap[0].searchFilter=uid={user} cas.authn.ldap[0].bindDn=cn=admin,dc=example,dc=org cas.authn.ldap[0].bindCredential=password cas.authn.ldap[0].principalAttributeList=employeeType:employeeType,uid:uid,sn:sn cas.authn.attributeRepository.defaultAttributesToRelease=employeeType,uid,sn

  5. cas-overlay-template/etc/cas/services/ 目录内新增 idp-1001.json 文件,注册我们的 idp 服务

    { "@class" : "org.apereo.cas.services.RegexRegisteredService", "serviceId" : "^(https)://idp.example.org.*" "name" : "idp", "id" : 1001, "evaluationOrder" : 10 }

  6. 执行 ./docker-build.sh 生成 docker 镜像。Dockerfilecas-overlay-template/Dockerfile 这个文件。实际上就是在容器里使用 ./gradlew clean build 编译 CAS。如果在服务器上准备好了 java 11 环境的话,直接执行 ./gradlew clean build 也是一样的,有兴趣的同学可以试试。

  7. 首次执行可能会有一点慢,耐心等待我们的容器镜像构建完成。

    Successfully built 6c1396544479 Successfully tagged org.apereo.cas/cas:6.1.4 Built CAS image successfully tagged as org.apereo.cas/cas:6.1.4 REPOSITORY TAG IMAGE ID CREATED SIZE org.apereo.cas/cas 6.1.4 6c1396544479 Less than a second ago 247MB

由于我们和 idp 装在一起,而 idptomcat 已经占用了 8080 端口,所以将其映射到 8081 上。

$ docker run -d -p 8081:8080 --name="cas" org.apereo.cas/cas:6.1.4
$ docker ps
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                              NAMES
8ed61668ad65        org.apereo.cas/cas:6.1.4   "java -server -nover…"   3 seconds ago       Up 2 seconds        8443/tcp, 0.0.0.0:8081->8080/tcp   cas

如果修改配置,则重新构建 docker,再重新运行构建好的容器即可。由于底层已经构建过,此时只替换了配置文件,所以速度是很快的。然后停掉当前容器,删除之再重新拉起即可。

$ docker stop cas
cas
$ docker rm cas
cas
$ docker run -d -p 8081:8080 --name="cas" org.apereo.cas/cas:6.1.4

这些过程实际上也就是 cas-overlay-template/docker-run.sh 内的内容,大家可以根据实际情况修改后。直接执行该脚本即可。

  1. 修改 httpd 的配置,在 idp.example.org 的对应的 VirtualHost 内,增加下述配置,然后重启 httpd 服务。

    ProxyPreserveHost On RequestHeader set X-Forwarded-Proto https RemoteIPHeader X-Forwarded-For ProxyPass "/cas/" "http://localhost:8081/cas/"

  2. 好拉,访问 https://idp.examle.org/cas/login ,看看 cas 是不是已经起来了?

对接 Shibboleth-IdP 3.4.6

我们使用 Unicon/shib-cas-authn3 插件来对接 IdP 和 CAS。由于 IdP 3.4.3 之后有一个内部 API 变更,因此插件的配置有大幅调整,实际上变得更简单了。实测表明新版版的插件(3.3.0)还修复了一些老版本的 bug——比如一个 CAS 属性无法同时映射给两个 IdP 属性的问题。建议大家尽量选择升级 IdP 到 3.4.6 后使用新版插件对接。

准备工作

以下假定 IdP 安装在 /opt/shibboleth-idp/

  • IdP 版本至少 3.4.6
安装
  • 把下载的 no-conversation-state.jsp 放入 /opt/shibboleth-idp/edit-webapp

  • 把下载的 cas-client-core-3.6.0.jarshib-cas-authenticator-3.3.0.jar 放入 /opt/shibboleth-idp/edit-webapp/WEB-INF/lib

  • /opt/shibboleth-idp/dist/webapp/WEB-INF/web.xml 拷贝到 /opt/shibboleth-idp/edit-webapp/WEB-INF/web.xml

    cp /opt/shibboleth-idp/dist/webapp/WEB-INF/web.xml /opt/shibboleth-idp/edit-webapp/WEB-INF/web.xml

  • 修改 /opt/shibboleth-idp/edit-webapp/WEB-INF/web.xml 增加以下部分

    ... ShibCas Auth Servlet net.unicon.idp.externalauth.ShibcasAuthServlet 2 ShibCas Auth Servlet /Authn/External/* ...

  • 修改 idp.properties 配置文件

    idp.authn.flows = External

    shibcas.casServerUrlPrefix = https://idp.example.org/cas shibcas.casServerLoginUrl = ${shibcas.casServerUrlPrefix}/login

    idp 的地址

    shibcas.serverName = https://idp.example.org

    如果不支持 cas3.0 协议,这里修改为 cas20 并取消注释

    shibcas.ticketValidatorName = cas30

运行 /opt/shibboleth-idp/bin/build.sh 重新编译 IdP ,然后重启 IdP 即可

属性映射
直接映射

AttributeDefinition 中的 xsi:type="SubjectDerivedAttribute" 为从插件中获取属性的配置,例如下面的示例表示将 cas 释放的 sn 映射为 cn

<AttributeDefinition xsi:type="SubjectDerivedAttribute" id="cn" principalAttributeName="sn">
        <AttributeEncoder xsi:type="SAML1String" name="urn:mace:dir:attribute-def:cn" encodeType="false" />
        <AttributeEncoder xsi:type="SAML2String" name="urn:oid:2.5.4.3" friendlyName="cn" encodeType="false" />
   </AttributeDefinition>
作为引用

如果 IdP 在属性释放时还需要进行一些特殊转换,即 xsi:type="ScriptedAttribute" 或者 xsi:type="Scoped" 等,那么可以先讲属性映射进来,再作为其他 AttributeDefinitionDependency 的引入,例如下面这个示例:先将 employeeType 获取到之后,标注为employeetype,然后引入到AttributeDefinition xsi:type="ScriptedAttribute" 中进行脚本计算。

<AttributeDefinition xsi:type="ScriptedAttribute" id="eduPersonScopedAffiliation">
        <Dependency ref="employeetype" />
        <Script><![CDATA[
        var localpart = "";
        if(employeetype.getValues().get(0)=="01") localpart = "staff";
        else if(employeetype.getValues().get(0)=="02") localpart = "student";
        else localpart = "other";
        
        eduPersonScopedAffiliation.addValue(localpart + "@%{idp.scope}");
            ]]></Script>
        <AttributeEncoder xsi:type="SAML1String" name="urn:mace:dir:attribute-def:eduPersonScopedAffiliation" encodeType="false" />
        <AttributeEncoder xsi:type="SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9" friendlyName="eduPersonScopedAffiliation" encodeType="false" />
    </AttributeDefinition>
    <AttributeDefinition xsi:type="SubjectDerivedAttribute" id="employeetype" principalAttributeName="employeeType"></AttributeDefinition>

以上

参考文献

  1. CAS Enterprise Single Sign-On
  2. apereo/cas-overlay-template
  3. Get Docker Engine - Community for CentOS
  4. Unicon/shib-cas-authn3
  5. 上海教育认证中心:IdP-CAS对接

转载授权

CC BY-SA

点赞
收藏
评论区
推荐文章
秃头王路飞 秃头王路飞
4个月前
webpack5手撸vue2脚手架
webpack5手撸vue相信工作个12年的小伙伴们在面试的时候多多少少怕被问到关于webpack方面的知识,本菜鸟最近闲来无事,就尝试了手撸了下vue2的脚手架,第一次发帖实在是没有经验,望海涵。languageJavaScript"name":"vuecliversion2","version":"1.0.0","desc
技术小男生 技术小男生
4个月前
linux环境jdk环境变量配置
1:编辑系统配置文件vi/etc/profile2:按字母键i进入编辑模式,在最底部添加内容:JAVAHOME/opt/jdk1.8.0152CLASSPATH.:$JAVAHOME/lib/dt.jar:$JAVAHOME/lib/tools.jarPATH$JAVAHOME/bin:$PATH3:生效配置
光头强的博客 光头强的博客
4个月前
Java面向对象试题
1、请创建一个Animal动物类,要求有方法eat()方法,方法输出一条语句“吃东西”。创建一个接口A,接口里有一个抽象方法fly()。创建一个Bird类继承Animal类并实现接口A里的方法输出一条有语句“鸟儿飞翔”,重写eat()方法输出一条语句“鸟儿吃虫”。在Test类中向上转型创建b对象,调用eat方法。然后向下转型调用eat()方
刚刚好 刚刚好
4个月前
css问题
1、在IOS中图片不显示(给图片加了圆角或者img没有父级)<div<imgsrc""/</divdiv{width:20px;height:20px;borderradius:20px;overflow:h
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
小森森 小森森
4个月前
校园表白墙微信小程序V1.0 SayLove -基于微信云开发-一键快速搭建,开箱即用
后续会继续更新,敬请期待2.0全新版本欢迎添加左边的微信一起探讨!项目地址:(https://www.aliyun.com/activity/daily/bestoffer?userCodesskuuw5n)\2.Bug修复更新日历2.情侣脸功能大家不要使用了,现在阿里云的接口已经要收费了(土豪请随意),\\和注意
晴空闲云 晴空闲云
4个月前
css中box-sizing解放盒子实际宽高计算
我们知道传统的盒子模型,如果增加内边距padding和边框border,那么会撑大整个盒子,造成盒子的宽度不好计算,在实务中特别不方便。boxsizing可以设置盒模型的方式,可以很好的设置固定宽高的盒模型。盒子宽高计算假如我们设置如下盒子:宽度和高度均为200px,那么这会这个盒子实际的宽高就都是200px。但是当我们设置这个盒子的边框和内间距的时候,那
艾木酱 艾木酱
3个月前
快速入门|使用MemFire Cloud构建React Native应用程序
MemFireCloud是一款提供云数据库,用户可以创建云数据库,并对数据库进行管理,还可以对数据库进行备份操作。它还提供后端即服务,用户可以在1分钟内新建一个应用,使用自动生成的API和SDK,访问云数据库、对象存储、用户认证与授权等功能,可专
Stella981 Stella981
1年前
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解2016年09月02日00:00:36 \牧野(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593
Stella981 Stella981
1年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
helloworld_28799839 helloworld_28799839
4个月前
常用知识整理
Javascript判断对象是否为空jsObject.keys(myObject).length0经常使用的三元运算我们经常遇到处理表格列状态字段如status的时候可以用到vue