CAS4.1单点登录实现(包含原理配置实现及简易demo)

CAS4.1单点登录实现(包含原理配置实现及简易demo),第1张

CAS4.1单点登录实现(包含原理配置实现及简易demo) CAS单点登录-简介

CAS 简介

CAS ( Central Authentication Service ) 是 Yale 大学发起的一个企业级的、开源的项目,旨在为 Web 应用系统提供一种可靠的单点登录解决方法(属于 Web SSO )。

SSO 简介

单点登录( Single Sign-On , 简称 SSO )是目前比较流行的服务于企业业务整合的解决方案之一, SSO 使得在多个应用系统中,用户只需要 登录一次 就可以访问所有相互信任的应用系统。

CAS 的基本原理

从结构体系看, CAS 包括两部分: CAS Server 和 CAS Client 。(服务端/客户端

服务端CAS Server 负责完成对用户的认证工作 , 需要独立部署 , CAS Server 会处理用户名 / 密码等凭证(Credentials) 。

客户端CAS Client 与受保护的客户端应用部署在一起,以 Filter 方式保护受保护的资源。CAS Client 负责处理对客户端受保护资源的访问请求,需要对请求方进行身份认证时,重定向到 CAS Server 进行认证。(原则上,客户端应用不再接受任何的用户名密码等 Credentials )。

基于CAS的SSO访问流程步骤:

访问服务: CAS Client 客户端发送请求访问应用系统提供的服务资源。

定向认证: CAS Client 客户端会重定向用户请求到 CAS Server 服务器。

用户认证: 用户在浏览器端输入用户验证信息,CAS Server服务端完成用户身份认证。

发放票据: CAS Server服务器会产生一个随机的 Service Ticket 。

验证票据: CAS Server服务器验证票据 Service Ticket 的合法性,验证通过后,允许客户端访问服务。

传输用户信息: CAS Server 服务器验证票据通过后,传输用户认证结果信息给客户端。

下面是 CAS 最基本的协议过程:

搭建CAS Server

首先下载cas-overlay,进入cas的git项目,选择版本,下载zip包并解压。(要求至少为jdk8,tomcat 8+)

https://github.com/apereo/cas-overlay-template

本demo中使用的cas server版本为4.1(maven版本),较高版本的server(如5.3)在代码拉取后自带了脚本,可直接用于打包构建。

(5.3之后的都是gradle项目,5.3以之前都是maven 项目,build.cmd为win版自动构建+运行的脚本,sh为linux版)

下面说明不使用脚本的server构建方式。

使用idea打开项目后,在较新的版本中,cas的很多配置都放在了cas.properties里,这个文件可以放在服务器的任何位置,但是需要修改propertyFileConfigurer.xml这个配置文件的目标路径,以告诉cas系统cas.properties需要去哪个位置加载。

下述截图标明了配置文件路径,右侧需对应修改cas.properties配置文件的存放路径,demo中我将配置文件放置于E:prop中,直接修改路径即可。

点击package将本项目打包,会生成一个上图路径target中的war文件:cas.war。该文件即打包好的cas server文件,将该war放入tomcat安装路径下的webapps文件夹中,启动tomcat,便会同时部署web应用程序cas server。

由于我的tomcat端口由8080修改为9527,当tomcat启动后,访问路径 http://localhost:9527/cas/login ,能见到cas登录页面时,说明本demo的cas服务端已安装部署成功。此时可尝试输入测试账号及密码,测试是否能实现登录功能。(静态账号casuser,密码Mellon)

也可以自己修改账号密码,在deployerConfigContext.xml文件内进行修改,如下图

至此,CAS Server的demo服务端搭建已完成。

编写CAS Client

为验证单点登录的有效性,新建立两个springboot项目,作为客户端2和客户端3。分别完成以下代码编写。当两个客户端及服务端1均启动时,若客户端2登录后,客户端3只需刷新页面即可同时处于已登录状态。

①引入CAS client依赖

在pom.xml中引入CAS Client的依赖包。代码如下:

net.unicon.cas

cas-client-autoconfig-support

2.3.0-GA





 

②配置

在application.properties或者application.yml中添加相关配置,主要配置内容包括服务器的相关地址,客户端的相关地址等。我这里是application.yml,配置内容如下:

(注意配置时的端口区分,本demo中,客户端2采用端口8890,客户端3采用端口9990)

cas:
#后端服务地址
client-host-url: http://127.0.0.1:8890
#cas认证中心地址
server-url-prefix: http://127.0.0.1:9527/cas
#cas认证中心登录地址
server-login-url: http://127.0.0.1:9527/cas/login
#Ticket校验器使用Cas30ProxyReceivingTicketValidationFilter
validation-type: cas3





 

③在启动类中添加启用注解

//启用CAS

@EnableCasClient

@SpringBootApplication

public class SpringBootSsoApplication { //省略部分内容 }

④编写测试接口Controller层

import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.validation.Assertion;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;


@RequestMapping("/casTest2")
@Controller
public class CASTestController {
@Value(value = "${cas.server-url-prefix}")
private String serverUrlPrefix = "";
@Value(value = "${cas.client-host-url}")
private String clientHostUrl = "";

@GetMapping("/user2")
@ResponseBody
public String user(HttpServletRequest request) {
Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
String loginName = null;
if (assertion != null) {
AttributePrincipal principal = assertion.getPrincipal();
loginName = principal.getName();
System.out.println("访问者2:" + loginName);
}
return "访问者2:" + loginName;
}

@GetMapping("/logout")
public String logout(HttpSession session) {
session.invalidate();
return "redirect:" + serverUrlPrefix + "/logout?service=" + clientHostUrl + "/casTest2/user2";
}

@GetMapping("/test2")
public String test() {
return "test2....";
}
}

实现CAS Client单点登录过程

测试过程:

初步测试时,开启服务端1、客户端2和客户端3。打开浏览器,输入地址http://127.0.0.1:9990/casTest3/user3,出现如下报错:(输入客户端2的接口地址同样报错)

显示错误信息:权限配置问题

  1. Application Not Authorized to Use CAS
  2. The application you attempted to authenticate toisnot authorized to use CAS.

解决办法:

修改Tomcat/webapps/cas/WEB-INF/classes/services目录下的HTTPSandIMAPS-10000001.Json文件:直接复制替换

{

"@class": "org.jasig.cas.services.RegexRegisteredService",

"serviceId" : "^(https|http|imaps)://.*",

"name": "https://localhost",

"id": 1,

"evaluationOrder": 0,

"logoutType": "BACK_CHANNEL",

"proxyPolicy" : {

"allowedToProxy": true,

"@class" : "org.jasig.cas.services.RegexMatchingRegisteredServiceProxyPolicy",

"pattern" : "^(https?)://localhost.*"

}

}

修改后重启服务端及客户端

此时访问客户端2接口地址,能够正常显示如下界面,允许输入用户名及密码,便于测试仍然使用默认账号及密码(账号:casuser,密码:Mellon)

输入相应用户名及密码后,登陆成功:

输入客户端3接口地址后访问,直接登陆成功

单点登录简易demo效果至此实现成功。为形成完整的登录登出流程,后续还需要实现cas单点登出。

注:上图所显示的错误Non-secure Connection,是由于没有使用HTTPS协议的关系,而默认的登陆界面有对此进行验证的代码,而在实际项目中的登陆界面一般需要自己写,通过修改webappscasWEB-INFviewjspdefaultui下的casLoginView.jsp即可。将下图所示代码删掉即可去除错误警告。

实现CAS Client单点登出过程

实现单点登出,需要在前文代码及配置的基础上进行。

首先需要添加服务端配置。

CAS服务端需进行相应的更改,在cas.properties中将下述配置改为true(若没有下述条目配置,则直接复制粘贴入文件中),添加配置后方可实现登出后的重定向,重定向地址为测试接口Controller层中编写的地址,当调用logout登出后,cas服务端发现该客户端不在登录状态,就会再次跳转到登录页,成功登录之后,便会再次跳转到目标接口路径。

# Specify whether CAS should redirect to the specified service parameter on /logout requests

cas.logout.followServiceRedirects=true

如果不添加此配置,就无法实现登出后的跳转,效果图如下(仅显示登出成功,而不会跳转到登录页)

其次是要注意测试接口Controller层中的注解使用。注意不要使用@RestController注解本类,而是使用@Controller注解,否则会导致重定向地址仅仅渲染在页面上,而不会实现页面跳转。

原因分析

@RestController注解相当于@ResponseBody + @Controller合在一起的作用

重定向失效即是@ResponseBody注解引起的。 @ResponseBody是作用在方法上的,@ResponseBody 表示该方法的返回结果直接写入 HTTP response body 中,一般在异步获取数据时使用【也就是AJAX】,在使用 @RequestMapping后,返回值通常解析为跳转路径,但是加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中。 比如异步获取 json 数据,加上 @ResponseBody 后,会直接返回 json 数据。@RequestBody 将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。

不会被解析成跳转路径,那么 return "redirect:” 重定向也就失效了。

因此解决方法就是把@RestController改成@Controller注解。

解决上述两点问题之后,重新启动服务端1、客户端2、客户端3。

实现单点登录 *** 作后,任选其中一方,访问其logout接口:

访问成功后,客户端2页面成功跳转至登录界面,回到客户端3,刷新页面,由于单点登出的效果,客户端3也处于离线状态,单点登出效果实现成功!

实际cas单点登录的应用场景,不可能只使用一个测试账号登录,因此需要实现cas与数据库相结合,实现自定义账号的单点登录登出,方有实际使用意义。

结合mysql数据库,实现CAS单点登出的客户及服务的交互过程

主要修改部分为 CAS Server的配置部分,通过在服务端配置数据源及相关验证,实现自定义用户及密码的登录替换,具体步骤及实施方式如下:

①新增cas登录的相关库表,具体库表语句如下:

# 创建测试数据库

CREATE DATAbase cas;

USE cas;

# 创建测试表

CREATE TABLE `cas_t_user` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`user_name` varchar(50) DEFAULT NULL,

`password` varchar(255) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

# 插入两条测试用户数据

INSERT INTO `cas_t_user` VALUES (1,'admin','96e79218965eb72c92a549dd5a330112');

INSERT INTO `cas_t_user` VALUES (2,'user','96e79218965eb72c92a549dd5a330112');



 

②修改配置文件内容,并新增部分配置内容

修改%tomcat_home%/webapps/cas/WEB_INF/deployerConfigContext.xml

首先注释掉下述代码(注释默认用户名和密码)









添加下述代码,MD5密码验证,数据库配置,认证类配置


>




>













③添加相关jar包

  • 目录:apache-tomcat-8.5.73webappscasWEB-INFlib
  • 在上面目录下添加以下三个jar包:

mysql-connector-java-5.1.46.jar

cas-server-support-jdbc-4.1.0.jar

c3p0-0.9.5.5.jar

(最开始使用了cas-server-support-jdbc-4.0.0.jar,发现输入正确的用户及密码时,无法实现正常页面跳转,且密码栏会被清空,切换为与本demo中的casServer版本完全匹配的jar后此问题被修复)

重启tomcat的服务端1,重启客户端2、客户端3进行测试

输入admin/111111

  • 其中用户的密码为MD5之后的值
  • “111111”的MD5值为:“96e79218965eb72c92a549dd5a330112”

效果如下图

可见,此时我们自己在数据库中添加的用户可以实现单点登录及单点登出。

cas客户端demo至此功能已全部实现。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5684700.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存