告别shiro-cas单点登录集成库,这款简单且强壮的Java Web安全引擎pac4j你值得拥有 -- 知识铺
告别shiro-cas单点登录集成库,这款简单且强壮的Java Web安全引擎pac4j你值得拥有
pac4j引擎全称为powerful authentication client for java,这是笔者根据其官网介绍推测的全称,不一定正确,姑且这样叫着。
一、缘何遇到该引擎
笔者在集成CAS单点登录服务时使用springboot+shiro
搭配shiro-cas
库,但是总是遇到非法令牌的问题即invalid_ticket,找了各种解释。
总之成功的都是相似的,不成功的原因千奇百怪。
更要命的是说,该库在退出的时候也有bug,折腾了许久,未果。
就在GitHub
上搜springboot shiro cas
,就出来了使用pac4j
引擎的项目,而且是一个很简单的纯测试项目。项目地址传送门。
下载跑起来测试一下,很舒服,直接成功。 😃
二、引擎能力
先来看一下这个安全引擎能够支持的框架,如下图,几乎包揽市面上的所有的框架,当然Shiro
和Spring Security
也在其中。在对接的时候引擎抽象了共同点使得工作变得简单。
支持的认证协议有:
OAuth (Facebook, Twitter, Google…) - SAML - CAS - OpenID Connect - HTTP - Google App Engine
LDAP - SQL - JWT - MongoDB - CouchDB - IP address - Kerberos (SPNEGO) - REST API
支持的授权类型有:
Roles/permissions - Anonymous/remember-me/(fully) authenticated - CORS - CSRF - HTTP Security headers
三、引擎特征
- 简单
- 高效
- 强壮
四、十大核心组件
序号 | 组件英文名称 | 组件中文名称 | 功能描述 |
---|---|---|---|
1 | client | 客户端 | 代表一个认证流程,执行登录逻辑并返回用户信息;UI认证的客户端称为间接客户端(indirect client),web服务认证的客户端称为直接客户端 |
2 | authenticator | 认证器 | 用于HTTP客户端认证身份, ProfileService 的子组件,ProfileService 不仅验证用户身份,还进行用户信息的创建、更新和删除 |
3 | authorizer | 授权器 | 基于网页上下文信息和用户信息进行权限验证 |
4 | matcher | 匹配器 | 定义安全性是否必须应用于安全过滤器 |
5 | config | 配置器 | 通过客户端、授权器和匹配器定义安全配置 |
6 | user profile | 用户身份 | 经过身份验证的用户的配置文件,具有标识符、属性、角色、权限、“记住我”性质和链接标识符 |
7 | web context | 用户身份 | 对pac4j实现的 HTTP 请求和响应以及关联表示会话的实现SessionStore 的抽象 |
8 | security filter | 安全过滤器 | 根据客户端和授权器的配置,通过检查用户是否经过身份验证以及授权是否有效来保护请求访问的 URL,如果用户未通过身份验证,则对直接客户端执行身份验证或为间接客户端启动登录过程 |
9 | callback endpoint | 回调点 | 表示间接客户端登录流程的结束 |
10 | logout endpoint | 登出点 | 处理应用或者身份服务器的登出 |
五、项目移植
笔者需要被集成的Web系统是基于Guns
后台开发,版本是beetle
版本,项目集成CAS基于spring-shiro-cas
移植。
5.1 导包
|
|
5.2 配置
|
|
5.3 重写认证和授权函数
|
|
5.4 调试
5.4.1 CAS验证原理
该图出自CAS官网,传送门。
5.4.2 单点登录流程分析
-
在浏览器中输入项目地址,
servlet
开始处理HTTP
请求 -
过滤器链中的过滤器执行动作逻辑,在
ShiroFilterFactoryBean
工厂类中定义一个包含4个过滤器的过滤器Map
表,分别是3个自定义和一个默认的过滤器UserFilter
:filterChainDefinitionMap.put("/", "securityFilter"); filterChainDefinitionMap.put("/callback", "callbackFilter"); filterChainDefinitionMap.put("/logout", "logoutFilter"); filterChainDefinitionMap.put("/**","user");
-
在
securityFilter
中,此时还没有任何用户的信息,仅仅是将访问的服务网站重定向到CAS服务器登陆地址,http://127.0.0.1:8080/cas/login?service=http%3A%2F%2F127.0.0.1%3A8082%2FiotProject%2Fcallback%3Fclient_name%3Dapp -
在登陆网页上填写用户名和密码信息后,继续执行过滤器
callbackFilter
,该过滤器的功能是利用CasAuthenticator
验证ticket
获取到中央认证服务器上用户的身份信息,接着BaseClient
创建用户信息UserProfile
,并将用户信息保存到Session
中完成信息的共享,在保存的函数中完成用户主体身份login
的流程,完成后重定向到受保护的网站即我们的服务网站 -
请求再次进到过滤器链中,因为服务地址对应的后台访问接口为
“/”
,对应着主页,先来看一下该函数:
|
|
因此又会进入到securityFilter
过滤器中,此时用户已经完成认证,认证成功后直接放行进到后台拦截器中即对应的接口函数中,后续需要用到权限的请求doGetAuthorizationInfo()
函数即可,至此完成单点登录功能。
5.5 完成
- 原文作者:知识铺
- 原文链接:https://index.zshipu.com/geek001/post/20240428/%E5%91%8A%E5%88%ABshiro-cas%E5%8D%95%E7%82%B9%E7%99%BB%E5%BD%95%E9%9B%86%E6%88%90%E5%BA%93%E8%BF%99%E6%AC%BE%E7%AE%80%E5%8D%95%E4%B8%94%E5%BC%BA%E5%A3%AE%E7%9A%84Java-Web%E5%AE%89%E5%85%A8%E5%BC%95%E6%93%8Epac4j%E4%BD%A0%E5%80%BC%E5%BE%97%E6%8B%A5%E6%9C%89--%E7%9F%A5%E8%AF%86%E9%93%BA/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。
- 免责声明:本页面内容均来源于站内编辑发布,部分信息来源互联网,并不意味着本站赞同其观点或者证实其内容的真实性,如涉及版权等问题,请立即联系客服进行更改或删除,保证您的合法权益。转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。也可以邮件至 sblig@126.com