告别shiro-cas单点登录集成库,这款简单且强壮的Java Web安全引擎pac4j你值得拥有

简介: 告别shiro-cas单点登录集成库,这款简单且强壮的Java Web安全引擎pac4j你值得拥有

pac4j官网地址传送门。


pac4j引擎全称为powerful authentication client for java,这是笔者根据其官网介绍推测的全称,不一定正确,姑且这样叫着。


一、缘何遇到该引擎


笔者在集成CAS单点登录服务时使用springboot+shiro搭配shiro-cas库,但是总是遇到非法令牌的问题即invalid_ticket,找了各种解释。


1.CAS服务器令牌失效时间短的问题

笔者更改配置文件,尝试多次,貌似不起作用,官方说的这是默认且唯一的配置;

2.缺少其它依赖库

引入后也不得行;

3.客户端应用路径问题

Url缺少“/”


总之成功的都是相似的,不成功的原因千奇百怪。


更要命的是说,该库在退出的时候也有bug,折腾了许久,未果。


就在GitHub上搜springboot shiro cas,就出来了使用pac4j引擎的项目,而且是一个很简单的纯测试项目。项目地址传送门

1666264617425.jpg

下载跑起来测试一下,很舒服,直接成功。 😃

1666264725838.jpg


二、引擎能力


先来看一下这个安全引擎能够支持的框架,如下图,几乎包揽市面上的所有的框架,当然Shiro和Spring Security也在其中。在对接的时候引擎抽象了共同点使得工作变得简单。

1666264799148.jpg

支持的认证协议有:


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. 简单
  2. 高效
  3. 强壮


四、十大核心组件


序号 组件英文名称 组件中文名称 功能描述
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 导包


<dependency>
   <groupId>org.apache.shiro</groupId>
   <artifactId>shiro-core</artifactId>
   <version>1.4.0</version>
   <exclusions>
       <exclusion>
           <artifactId>slf4j-api</artifactId>
           <groupId>org.slf4j</groupId>
       </exclusion>
   </exclusions>
</dependency>
<dependency>
   <groupId>org.apache.shiro</groupId>
   <artifactId>shiro-spring</artifactId>
   <version>1.4.0</version>
</dependency>
<dependency>
    <groupId>io.buji</groupId>
    <artifactId>buji-pac4j</artifactId>
    <version>4.0.0</version>
</dependency>
<dependency>
    <groupId>org.pac4j</groupId>
    <artifactId>pac4j-cas</artifactId>
    <version>3.3.0</version>
</dependency>

5.2 配置

cas:
  client-name: app
  server:
   url: http://127.0.0.1:8080/cas
  project:
   url: http://127.0.0.1:8082/iotProject


5.3 重写认证和授权函数


/**
 * 认证
 *
 * @param authenticationToken
 * @return
 * @throws AuthenticationException
 */
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)throws AuthenticationException {
    final Pac4jToken pac4jToken = (Pac4jToken) authenticationToken;
    final List<CommonProfile> commonProfileList = pac4jToken.getProfiles();
    final CommonProfile commonProfile = commonProfileList.get(0);
    logger.info("单点登录返回的信息" + commonProfile.toString());
//        final Pac4jPrincipal principal = new Pac4jPrincipal(commonProfileList,getPrincipalNameAttribute());
    UserAuthService shiroFactory = UserAuthServiceServiceImpl.me();
    User user = shiroFactory.user(commonProfile.getId());
    ShiroUser shiroUser = shiroFactory.shiroUser(user);
    final PrincipalCollection principalCollection = new SimplePrincipalCollection(shiroUser, getName());
    return new SimpleAuthenticationInfo(principalCollection,commonProfileList.hashCode());
}
/**
 * 授权/验权(todo 后续有权限在此增加)
 *
 * @param principals
 * @return
 */
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    UserAuthService shiroFactory = UserAuthServiceServiceImpl.me();
    ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal();
    List<Long> roleList = shiroUser.getRoleList();
    Set<String> permissionSet = new HashSet<>();
    Set<String> roleNameSet = new HashSet<>();
    for (Long roleId : roleList) {
        List<String> permissions = shiroFactory.findPermissionsByRoleId(roleId);
        if (permissions != null) {
            for (String permission : permissions) {
                if (ToolUtil.isNotEmpty(permission)) {
                    permissionSet.add(permission);
                }
            }
        }
        String roleName = shiroFactory.findRoleNameByRoleId(roleId);
        roleNameSet.add(roleName);
    }
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    info.addStringPermissions(permissionSet);
    info.addRoles(roleNameSet);
    return info;
}

5.4 调试


5.4.1 CAS验证原理


该图出自CAS官网,传送门

1666265069449.jpg


5.4.2 单点登录流程分析


1.在浏览器中输入项目地址,servlet开始处理HTTP请求


2.过滤器链中的过滤器执行动作逻辑,在ShiroFilterFactoryBean工厂类中定义一个包含4个过滤器的过滤器Map表,分别是3个自定义和一个默认的过滤器UserFilter:


filterChainDefinitionMap.put("/", "securityFilter");
filterChainDefinitionMap.put("/callback", "callbackFilter");
filterChainDefinitionMap.put("/logout", "logoutFilter");
filterChainDefinitionMap.put("/**","user");

3.在securityFilter中,此时还没有任何用户的信息,仅仅是将访问的服务网站重定向到CAS服务器登陆地址,http://127.0.0.1:8080/cas/login?service=http%3A%2F%2F127.0.0.1%3A8082%2FiotProject%2Fcallback%3Fclient_name%3Dapp


4.在登陆网页上填写用户名和密码信息后,继续执行过滤器callbackFilter,该过滤器的功能是利用CasAuthenticator验证ticket获取到中央认证服务器上用户的身份信息,接着BaseClient创建用户信息UserProfile,并将用户信息保存到Session中完成信息的共享,在保存的函数中完成用户主体身份login的流程,完成后重定向到受保护的网站即我们的服务网站


5.请求再次进到过滤器链中,因为服务地址对应的后台访问接口为“/”,对应着主页,先来看一下该函数:


/**
 * 跳转到主页
 */
@RequestMapping(value = "/", method = RequestMethod.GET)
public String index(Model model, HttpServletRequest request, HttpServletResponse response) {
    //获取当前用户角色列表
    ShiroUser user = ShiroKit.getUserNotNull();
    List<Long> roleList = user.getRoleList();
    if (roleList == null || roleList.size() == 0) {
        ShiroKit.getSubject().logout();
        model.addAttribute("tips", "该用户没有角色,无法登陆");
        return "/login.html";
    }
    List<MenuNode> menus = userService.getUserMenuNodes(roleList);
    model.addAttribute("menus", menus);
    return "/index.html";
}

因此又会进入到securityFilter过滤器中,此时用户已经完成认证,认证成功后直接放行进到后台拦截器中即对应的接口函数中,后续需要用到权限的请求doGetAuthorizationInfo()函数即可,至此完成单点登录功能。


5.5 完成


相关文章
|
3月前
|
安全 Java API
Java Web 在线商城项目最新技术实操指南帮助开发者高效完成商城项目开发
本项目基于Spring Boot 3.2与Vue 3构建现代化在线商城,涵盖技术选型、核心功能实现、安全控制与容器化部署,助开发者掌握最新Java Web全栈开发实践。
371 1
|
3月前
|
存储 前端开发 Java
【JAVA】Java 项目实战之 Java Web 在线商城项目开发实战指南
本文介绍基于Java Web的在线商城技术方案与实现,涵盖三层架构设计、MySQL数据库建模及核心功能开发。通过Spring MVC + MyBatis + Thymeleaf实现商品展示、购物车等模块,提供完整代码示例,助力掌握Java Web项目实战技能。(238字)
337 0
|
5月前
WEB端交互元件库:Axure设计师的高效利器
EQL UI是一款功能强大、组件丰富的Axure元件库,涵盖500+设计组件与完整后台模板,助力设计师高效搭建高保真原型,提升产品设计效率与质量。
787 128
|
3月前
|
人工智能 Java API
Java与大模型集成实战:构建智能Java应用的新范式
随着大型语言模型(LLM)的API化,将其强大的自然语言处理能力集成到现有Java应用中已成为提升应用智能水平的关键路径。本文旨在为Java开发者提供一份实用的集成指南。我们将深入探讨如何使用Spring Boot 3框架,通过HTTP客户端与OpenAI GPT(或兼容API)进行高效、安全的交互。内容涵盖项目依赖配置、异步非阻塞的API调用、请求与响应的结构化处理、异常管理以及一些面向生产环境的最佳实践,并附带完整的代码示例,助您快速将AI能力融入Java生态。
478 12
|
4月前
|
JavaScript Java 微服务
现代化 Java Web 在线商城项目技术方案与实战开发流程及核心功能实现详解
本项目基于Spring Boot 3与Vue 3构建现代化在线商城系统,采用微服务架构,整合Spring Cloud、Redis、MySQL等技术,涵盖用户认证、商品管理、购物车功能,并支持Docker容器化部署与Kubernetes编排。提供完整CI/CD流程,助力高效开发与扩展。
488 64
|
4月前
|
前端开发 Java 数据库
Java 项目实战从入门到精通 :Java Web 在线商城项目开发指南
本文介绍了一个基于Java Web的在线商城项目,涵盖技术方案与应用实例。项目采用Spring、Spring MVC和MyBatis框架,结合MySQL数据库,实现商品展示、购物车、用户注册登录等核心功能。通过Spring Boot快速搭建项目结构,使用JPA进行数据持久化,并通过Thymeleaf模板展示页面。项目结构清晰,适合Java Web初学者学习与拓展。
308 1
|
4月前
|
人工智能 自然语言处理 分布式计算
AI 驱动传统 Java 应用集成的关键技术与实战应用指南
本文探讨了如何将AI技术与传统Java应用集成,助力企业实现数字化转型。内容涵盖DJL、Deeplearning4j等主流AI框架选择,技术融合方案,模型部署策略,以及智能客服、财务审核、设备诊断等实战应用案例,全面解析Java系统如何通过AI实现智能化升级与效率提升。
335 0
|
5月前
|
缓存 NoSQL Java
Java Web 从入门到精通之苍穹外卖项目实战技巧
本项目为JavaWeb综合实战案例——苍穹外卖系统,涵盖Spring Boot 3、Spring Cloud Alibaba、Vue 3等主流技术栈,涉及用户认证、订单处理、Redis缓存、分布式事务、系统监控及Docker部署等核心功能,助你掌握企业级项目开发全流程。
581 0
|
5月前
|
安全 JavaScript Java
java Web 项目完整案例实操指南包含从搭建到部署的详细步骤及热门长尾关键词解析的实操指南
本项目为一个完整的JavaWeb应用案例,采用Spring Boot 3、Vue 3、MySQL、Redis等最新技术栈,涵盖前后端分离架构设计、RESTful API开发、JWT安全认证、Docker容器化部署等内容,适合掌握企业级Web项目全流程开发与部署。
337 0
|
6月前
|
监控 安全 Java
Java 开发中基于 Spring Boot 3.2 框架集成 MQTT 5.0 协议实现消息推送与订阅功能的技术方案解析
本文介绍基于Spring Boot 3.2集成MQTT 5.0的消息推送与订阅技术方案,涵盖核心技术栈选型(Spring Boot、Eclipse Paho、HiveMQ)、项目搭建与配置、消息发布与订阅服务实现,以及在智能家居控制系统中的应用实例。同时,详细探讨了安全增强(TLS/SSL)、性能优化(异步处理与背压控制)、测试监控及生产环境部署方案,为构建高可用、高性能的消息通信系统提供全面指导。附资源下载链接:[https://pan.quark.cn/s/14fcf913bae6](https://pan.quark.cn/s/14fcf913bae6)。
963 0