如何使用CAS 5 实现单点登录(一、搭建服务端)

前言

前端时间公司让我研究一下单点登录,主要目的是如何在现有的框架中引入单点登录功能。说实话,由于之前没有接触过,而且网上资料质量参差不齐,甚至有些误人子弟,让我在实现过程中踩了不少坑。现在,我将一些学习和实践的心得通过本文记录下来,希望能或多或少帮到大家。

起初,我打算仅用一篇文章完成介绍,但我的目标是尽量能浅显易懂,并且为了能让大家方便复现,所以最终决定以系列的形式进行探讨。

概要

单点登录和CAS

单点登录(Single Sign On),简称 SSO,其概念网上一搜便知,我不做废话。简单来说,就是只要一次登录了某个子系统,就顺带登录了其他的子系统。其目的很简单,就是为了减少用户访问子系统的成本。

目前,实现单点登录最流行的是CAS框架,这是一个由耶鲁大学主导的开源框架,github地址为:
https://github.com/apereo/cas

截止本文撰写时,最新稳定版本为5.3.2。网上的资料教程大多数都是基于4.X版本,已经严重过时,2016年后官方也不在更新维护,不再推荐大家使用。

CAS 5.X要求JDK版本最低为1.8。并且基于Spring Boot进行了大幅重构,其使用方式以较4.X大相径庭,另外,5.X也引入了更多的特性。具体请参见官方文档

需要注意的一点是,在4.X时代,CAS由jasig社区托管,在5.X时代,CAS已被apereo社区托管,因此,大家在maven下载依赖时,要注意区分,如:

  • apereo
<dependency>
    <groupId>org.apereo.cas</groupId>
    <artifactId>cas-server-core</artifactId>
    <version>5.3.2</version>
    <scope>test</scope>
</dependency>
  • jasig
<dependency>
    <groupId>org.jasig.cas</groupId>
    <artifactId>cas-server-core</artifactId>
    <version>4.2.7</version>
</dependency>

CAS原理

CAS的原理稍稍有些复杂,我们至少要了解TGT、TGC、ST这个三个核心概念,以及整个单点登录的实现过程。强烈推荐博文《前端需要了解的 SSO 与 CAS 知识》,建议大家务必提前细细品味,钻研透彻,否则后续的实现过程会让你觉得云里雾里。

了解了CAS的原理后,还需要注意一点,CAS默认是基于浏览器的单点登录方式,其依赖于浏览器的cookie和重定向机制。但是,由于移动互联网的发展,客户端的接入方式已经不限于浏览器,我们更多的需要支持原生应用(如安卓、IOS)的接入。因此,CAS的基于cookie和重定向机制的浏览器登录认证方式有了很大的局限性。另外,当下前后端分离的开发形式已非常广泛,前后端之间都通过REST接口进行请求。

基于上面的因素,CAS又单独提供了REST的扩展。本系列对两种方式(浏览器方式、REST方式)的实现都会进行介绍。

实现服务端

CAS是由客户端和服务端两部分构成的,本文将先介绍服务端的实现过程,IDE使用Idea 2018,JDK使用1.8,Gradle使用4.4。

服务端实际上是一个Web工程,需要放在Web容器如Tomcat中运行。CAS官方推荐采用overlay方式来实现服务端,详见官方文档

何为overlay,中文意为覆盖。一言以蔽之,overlay就是官方提供给你一个模板工程,我们只需要将修改或定制的文件覆盖模板工程中对应位置的对应文件(包括代码和资源文件)即可。

为何需要overlay,官方解释很清楚:

  • There is no need to download/build from the source.
  • Upgrades are tremendously easier in most cases by simply adjusting the build script to download the newer CAS release.
  • Rather than hosting the entire software source code, as the deployer you ONLY keep your own local customizations which makes change tracking much easier.
  • Tracking changes inside a source control repository is very lightweight, again simply because only relevant changes (and not the entire software) is managed.

以上,我认为最关键有两点:

  • 如果直接修改源码,CAS特性升级后源码有变动,我们还得重新适配我们的修改
  • 使用overlay,由于不直接修改源码,我们可以方便的追踪自己定制的功能,可以清楚的知道我们修改了哪些

1.下载cas-overlay-template工程

首先,下载cas-overlay-template工程。CAS同时提供了maven和gradle两个类型,大同小异,本文将基于gradle进行介绍,请戳下载地址

使用Idea打开工程,等待依赖下载后,工程如下:


image.png

该工程的gradle构建文件稍许复杂,有些功能或许暂时用不上。并且,如果在一个已有的老旧系统中引入CAS,直接用cas-overlay-template工程当然不合适,势必需要进行修改。所以,本文将抽取其关键核心的配置,取其精华,重新创建新的工程做以示范。

另外,根据官方介绍,该工程支持两种运行方式:

  1. 通过java -jar *.war启动
  2. 通过部署至Web容器(如tomcat)启动

对于方式1,实际上是因为cas-overlay-template这个Spring Boot工程内嵌了tomcat容器,总所周知,这也是Spring Boot推荐的运行方式。方式2实际上是最常见的、标准的Java Web工程的运行方式。这里,由于方式1相对较简单,本文将基于方式2进行介绍。

2.搭建服务端工程

我们重点关注cas-overlay-template工程中cas模块的build.gradle文件,稍许复杂,我们只聚焦其依赖:

dependencies {
    compile "org.apereo.cas:cas-server-webapp-tomcat:${project.'cas.version'}@war"
    if (!project.hasProperty('bootiful')) {
        // Other dependencies may be listed here...
    } else {
        println "Running CAS in Bootiful mode; all dependencies except the CAS web application are ignored."
    }
}

结合gradle.properteis,可以发现该工程只依赖于:
org.apereo.cas:cas-server-webapp-tomcat:5.3.2@war

在菜单Build/Build Artifacts中进行构建,选择exploded

image.png

image.png

执行后,在build目录中可以看到war文件:


image.png

我们将基于这个war文件搭建自己的服务端。新建gradle工程,结构如下:


image.png

build.gradle由cas-overlay-template进行精简,如下:

group 'com.mystudy.cas'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: "org.springframework.boot"
apply plugin: "war"

sourceCompatibility = 1.8

buildscript {
    repositories {
        mavenLocal()
        jcenter()
    }
    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:1.5.14.RELEASE"
    }
}

springBoot {
    mainClass = "org.springframework.boot.loader.WarLauncher"
}

bootRepackage {
    mainClass = "org.apereo.cas.web.CasWebApplication"
    executable = false
    excludeDevtools = false
}

bootRun {
    addResources = true
    classpath = sourceSets.main.compileClasspath
}

war {
    baseName 'cas'
    entryCompression = ZipEntryCompression.STORED
}

repositories {
    mavenCentral()
}

dependencies {
    compile "org.apereo.cas:cas-server-webapp-tomcat:5.3.2@war"
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

src\main下新建包webapp,然后解压上一小节获取的war包,将META-INForgWEB-INF目录拷贝至webapp内:

image.png

如上,可以看到这是一个标准的Web工程。CAS默认设计了基本的Web页面(基于angular和thymeleaf),在此基础上我们可以按需定制。

另外,WEB-INF\lib目录中的依赖文件较多,有334个。很明显,使用overlay方式,我们不得不将这些依赖维护到代码仓库中,这是因为官方并没有提供这些文件的直接依赖(只能通过war解压获取)。当然,不得已的话你也可以直接使用源码进行开发不使用overlay方式。

根据overlay的思路,我们只需要在源码路径src\main中进行定制,并将所有自定义配置文件都放置在src\main\resources中,但若要修改CAS的配置,一定要保证配置文件的路径和名称与webapp\WEB-INF中一致。

比如,我们要修改WEB-INF\application.properties这个Spring Boot配置文件中的server.port,我们只需要拷贝其至src\main\resources目录下进行修改,并且备份WEB-INF中的application.properties为其他名称(如application2.properties)即可。这样,构建后的War包中的WEB-INF就会替换为自己的配置文件。

这里提一个小常识,src\main中的所有源码和资源文件在构建后,都会依照包路径保存到WEB-INF\classes目录下,而外部的依赖会全部保存到WEB-INF\lib目录下。

3.服务端运行

至此,我们已经搭建起一个最基本的Hello World,现在使用Idea配合Tomcat进行启动。先配置Tomcat,修改Deployment,添加部署构建:

image.png

Server保持如下设置即可:

image.png

在Idea中启动Tomcat,耐心等上片刻,期间将会看到如下蓝色提示信息:


image.png

启动成功后,开始监听请求,提示“READY":


image.png

并且,Idea会自动打开浏览器去访问CAS自带的登录界面:


image.png

账号密码在哪里?请看application.properties最后:

##
# CAS Authentication Credentials
#
cas.authn.accept.users=casuser::Mellon

如上,用户名为casuser,密码为Mellon,登录成功后提示:

image.png

当然,我们可以在application.properties中修改用户名和密码(别忘了拷贝application.properties)。

废话

到目前为止,我们搭建了一个简单的CAS服务端,下一章节《如何使用CAS 5 实现单点登录(二、搭建客户端)》敬请期待。

本人水平有限,难免有错误或遗漏之处,望大家指正和谅解,欢迎评论留言。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容