一、简介
在之前文章 Cas 5.2.x版本使用 —— 实现SSO单点登录(九) 讲解过如何实现单点登录。 相信大家也看到了,都是跳转到了同一个登录界面。本章节围着这个项目继续开展。
假设现在我有两个子站点,app1.com,app2.com. 两个站点使用不同的样式。那该如何操作呢?
1、主题?
先介绍下什么叫主题,主题就意味着风格不一,目的就是为了在不同的接入端(service)展示不同的页面,就例如淘宝登录、天猫登录,其中登录点还是一个sso,但淘宝登录卖的广告是淘宝的,而天猫登录卖的广告是天猫的。
简略看完后,会有以下的规范:
静态资源(js,css)存放目录为
src/main/resources/static
html资源存(thymeleaf)放目录为
src/main/resources/templates
主题配置文件存放在
src/main/resources
并且命名为[theme_name].properties主题页面html存放目录为
src/main/resources/templates/<theme-id>
2、主题渲染是怎么样的?
官方文档明确说明,登录页渲染文件为casLoginView.html
,那意味我们在主题具体目录下新增改文件并且按照cas要求写那就可以了
最终目的还是获取到对应的配置文件,渲染对应主题的登录页
3、接入服务如何指定主题?
{ "@class" : "org.apereo.cas.services.RegexRegisteredService", "serviceId" : "^https://www.example.org", "name" : "MyTheme", "theme" : "[theme_name]", "id" : 1000 }
theme
为key指定配置文件id
若主题配置文件为test_theme.application
则"theme":"test_theme"
4、如何修改默认主题?
application.properties
cas.theme.defaultThemeName=[theme_id]
配置默认后,将直接指定该主题,比如直接访问cas登录,没有传递service参数时等。
二、实战
项目结构
1、service服务注册配置
app1-1000001.json
{ "@class": "org.apereo.cas.services.RegexRegisteredService", "serviceId": "^(https|http)://app1.*", "name": "app1", "id": 100001, "description": "这是一个app1域名下的服务,通过app1访问都允许通过", "evaluationOrder": 10, "theme": "app1" }
app2-1000002.json
{ "@class": "org.apereo.cas.services.RegexRegisteredService", "serviceId": "^(https|http)://app2.*", "name": "app2", "id": 100002, "description": "这是一个app2域名下的服务,通过app2访问都允许通过", "evaluationOrder": 11, "theme": "app2" }
2、css样式表
app1/css/main.css
设置一个标题为粉色
h3 { color: pink; /**粉色**/ }
app2/css/main.css
设置一个标题为红色
h3 { color: red; /**红色**/ }
3、主题配置文件
app1.properties
css.file=/themes/app1/css/main.css pageTitle= 这是APP 1 网站 #standard.custom.css.file=/themes/[theme_name]/css/cas.css #cas.javascript.file=/themes/[theme_name]/js/cas.js standard.custom.css.file=/css/cas.css admin.custom.css.file=/css/admin.css cas.javascript.file=/js/cas.js
app2.properties
css.file=/themes/app2/css/main.css pageTitle= 这是APP 2 网站 #standard.custom.css.file=/themes/[theme_name]/css/cas.css #cas.javascript.file=/themes/[theme_name]/js/cas.js standard.custom.css.file=/css/cas.css admin.custom.css.file=/css/admin.css cas.javascript.file=/js/cas.js
这个和上一个差不多,但是注意一点,id、evaluationOrder、theme这三个配置不要和别的站点重复了,evaluationOrder 指的是匹配的顺序,越小越优先匹配。
4、登录模版
casLoginView.html 我的demo 演示中app1和app2的模版文件内容相同,主要是css颜色控制差异,当然你可以随意更改html内容表示不同。
html中使用webflow语法,获取app.properties
文件中的内容。
比如 <h3 th:text="${#themes.code('pageTitle')}"></h3>
,pageTitle
就是app.properties
中的pageTitle
值
注意要点:from表单的内容需要遵循一定的标准th:object
等等
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title th:text="${#themes.code('pageTitle')}"></title> <link rel="stylesheet" th:href="@{${#themes.code('css.file')}}" /> </head> <body> <h3 th:text="${#themes.code('pageTitle')}"></h3> <div> <form method="post" th:object="${credential}"> <div th:if="${#fields.hasErrors('*')}"><span th:each="err : ${#fields.errors('*')}" th:utext="${err}" /> </div> <h4 th:utext="#{screen.welcome.instructions}"></h4> <section class="row"> <label for="username" th:utext="#{screen.welcome.label.netid}" /> <div th:unless="${openIdLocalId}"> <input class="required" id="username" size="25" tabindex="1" type="text" th:disabled="${guaEnabled}" th:field="*{username}" th:accesskey="#{screen.welcome.label.netid.accesskey}" autocomplete="off" th:value="casuser" /> </div> </section> <section class="row"> <label for="password" th:utext="#{screen.welcome.label.password}" /> <div> <input class="required" type="password" id="password" size="25" tabindex="2" th:accesskey="#{screen.welcome.label.password.accesskey}" th:field="*{password}" autocomplete="off" th:value="Mellon" /> </div> </section> <section> <input type="hidden" name="execution" th:value="${flowExecutionKey}" /> <input type="hidden" name="_eventId" value="submit" /> <input type="hidden" name="geolocation" /> <input class="btn btn-submit btn-block" name="submit" accesskey="l" th:value="#{screen.welcome.button.login}" tabindex="6" type="submit" /> </section> </form> </div> </body> </html>
5、启用识别
配置application.properties
,设置cas需要从json文件做初始化操作,不然我们配置的json没有生效
#开启识别json文件,默认false cas.serviceRegistry.initFromJson=true #自动扫描服务配置,默认开启 #cas.serviceRegistry.watcherEnabled=true #120秒扫描一遍 #cas.serviceRegistry.repeatInterval=120000 #延迟15秒开启 #cas.serviceRegistry.startDelay=15000 #默认json/yml资源加载路径为resources/services #cas.serviceRegistry.config.location=classpath:/services
三、测试访问
访问 app1 受限URL跳转登录
访问 app2 受限URL跳转登录
四、视频演示Demo
https://v.qq.com/x/page/v0633n7q9eu.html
五、我的源码
https://github.com/X-rapido/CAS_SSO_Record/tree/master/custom-themes-sso
六、参考文档
https://apereo.github.io/cas/5.2.x/installation/User-Interface-Customization.html
https://apereo.github.io/cas/5.2.x/installation/Configuration-Properties.html#themes
https://blog.csdn.net/u010475041/article/details/78201261
https://blog.csdn.net/yelllowcong/article/details/79236506