cas 6 单点登录登出管理

news2024/11/14 11:03:28

cas自带的登出是通过登出地址后面接的service地址进行跳转,但是对于service没有进行验证,这边我们网络渗透测试后说可能被钓鱼需要进行验证所以开始了以下操作。

1找资料

首先到cas官网找,发现项目有自带的是否跳转,跳转地址参数名称,跳转地址配置等数据

2.找代码 其中重点配置的是否跳转参数,我们知道java的bean可以将读取配置的-视为下一个字母大写,所以我在jar包中搜索followServiceRedirects

还有在实体类中看到需要引入包

 所以在build.gradle中的dependencies下层次

加入

implementation "org.apereo.cas:cas-server-core-logout:${casServerVersion}"

具体位置如下

3.代码解读

圈中的地方为判断service地址是不是为空,并且followServiceRedirects为真 进行跳转

 这就表明只要我们在这边加个查询 跳转的service是不是在自己的数据库里面就成,具体怎么做我就不赘述了,大家需求不同,因为我这边开始会将数据载入在servicesManager中 我直接读就行,我们来看看如何替换掉它,

其中点击方法发现只有3个地方有写到这个类,其中第一个是自身,后面两个来自一个启动配置

然后就看到这个bean 是新建这个类的东西,而且上面使用了@ConditionalOnMissingBean

 也就是说只要我再写一个bean叫同一个名字,他就会加载我的了,所以我写了个config

继续点击方法看看引用

发现下面那个方法有加载,所以我重写了这俩到一个配置文件,并切新建了一个自定义规则的文件

package com.fgi.logout.cofig;

import com.fgi.logout.strategy.CustomLogoutRedirectionStrategy;
import org.apereo.cas.authentication.principal.ServiceFactory;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.logout.LogoutExecutionPlanConfigurer;
import org.apereo.cas.logout.LogoutRedirectionStrategy;
import org.apereo.cas.logout.config.CasCoreLogoutConfiguration;
import org.apereo.cas.logout.slo.SingleLogoutServiceLogoutUrlBuilder;
import org.apereo.cas.ticket.registry.TicketRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author LinZuo
 * @date 2023-06-07$ $
 */
@Configuration("logoutRedirectionConfiguration")
public class LogoutRedirectionConfiguration {
    private static final Logger LOGGER = LoggerFactory.getLogger(SingleLogoutTriggerConfiguration.class);
    @Autowired
    private CasCoreLogoutConfiguration casCoreLogoutConfiguration;

    @Autowired
    private CasConfigurationProperties casProperties;

    @Autowired
    @Qualifier("ticketRegistry")
    private ObjectProvider<TicketRegistry> ticketRegistry;

    @Autowired
    @Qualifier("webApplicationServiceFactory")
    private ObjectProvider<ServiceFactory> webApplicationServiceFactory;

    @Autowired
    @Qualifier("singleLogoutServiceLogoutUrlBuilder")
    private ObjectProvider<SingleLogoutServiceLogoutUrlBuilder> singleLogoutServiceLogoutUrlBuilder;

    @Bean
    @RefreshScope
    @ConditionalOnMissingBean(name = "casCoreLogoutExecutionPlanConfigurer")
    public LogoutExecutionPlanConfigurer casCoreLogoutExecutionPlanConfigurer() {
        return plan -> {
            plan.registerSingleLogoutServiceMessageHandler(casCoreLogoutConfiguration.defaultSingleLogoutServiceMessageHandler());
            plan.registerLogoutRedirectionStrategy(defaultLogoutRedirectionStrategy());

            if (casProperties.getLogout().isRemoveDescendantTickets()) {
                LOGGER.debug("CAS is configured to remove descendant tickets of the ticket-granting tickets");
                plan.registerLogoutPostProcessor(ticketGrantingTicket -> ticketGrantingTicket.getDescendantTickets()
                        .forEach(t -> {
                            LOGGER.debug("Deleting ticket [{}] from the registry as a descendant of [{}]", t, ticketGrantingTicket.getId());
                            ticketRegistry.getObject().deleteTicket(t);
                        }));
            }
        };
    }

    @Bean
    @RefreshScope
    @ConditionalOnMissingBean(name = "defaultLogoutRedirectionStrategy")
    public LogoutRedirectionStrategy defaultLogoutRedirectionStrategy() {
        return new CustomLogoutRedirectionStrategy(webApplicationServiceFactory.getObject(),
                casProperties.getLogout(), singleLogoutServiceLogoutUrlBuilder.getObject());
    }
}
package com.fgi.logout.strategy;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.fgi.service.ServiceManagerUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.apereo.cas.authentication.principal.ServiceFactory;
import org.apereo.cas.authentication.principal.WebApplicationService;
import org.apereo.cas.configuration.model.core.logout.LogoutProperties;
import org.apereo.cas.logout.LogoutRedirectionStrategy;
import org.apereo.cas.logout.slo.SingleLogoutServiceLogoutUrlBuilder;
import org.apereo.cas.services.RegisteredService;
import org.apereo.cas.services.ServicesManager;
import org.apereo.cas.web.support.WebUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.webflow.execution.RequestContext;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
/**
 * This is {@link CustomLogoutRedirectionStrategy}.
 *
 * @author Misagh Moayyed
 * @since 6.3.0
 */
@RequiredArgsConstructor
@Slf4j
public class CustomLogoutRedirectionStrategy implements LogoutRedirectionStrategy {
    private final ServiceFactory<WebApplicationService> webApplicationServiceFactory;

    private final LogoutProperties logoutProperties;

    private final SingleLogoutServiceLogoutUrlBuilder singleLogoutServiceLogoutUrlBuilder;

    @Resource
    @Qualifier("servicesManager")
    private ServicesManager servicesManager;

    @Override
    public boolean supports(final RequestContext context) {
        return context != null;
    }

    @Override
    public void handle(final RequestContext requestContext) {
        val request = WebUtils.getHttpServletRequestFromExternalWebflowContext(requestContext);
        val paramName = logoutProperties.getRedirectParameter();
        log.trace("Using parameter name [{}] to detect destination service, if any", paramName);
        val service = requestContext.getRequestParameters().get(paramName);
        log.trace("Located target service [{}] for redirection after logout", service);
        // 添加的代码 判断登出地址中是否有当前跳转的地址 s
        Collection<RegisteredService> list = servicesManager.getAllServices();
        List<String> serviceIds = ServiceManagerUtil.getServiceId(service);
        boolean exists = list.stream().anyMatch(s-> {
            if(CollectionUtil.isEmpty(serviceIds)){
                return false;
            }
            return StrUtil.isNotBlank(s.getLogoutUrl())&& s.getRedirectUrl().equals(serviceIds.get(0));
        });
        // 添加的代码 判断登出地址中是否有当前跳转的地址 e
        val authorizedRedirectUrlFromRequest = WebUtils.getLogoutRedirectUrl(request, String.class);
        if (StringUtils.isNotBlank(service) && logoutProperties.isFollowServiceRedirects()&&exists) {
            val webAppService = webApplicationServiceFactory.createService(service);
            if (singleLogoutServiceLogoutUrlBuilder.isServiceAuthorized(webAppService, Optional.of(request))) {
                log.debug("Redirecting to logout URL [{}]", service);
                WebUtils.putLogoutRedirectUrl(requestContext, service);
            } else {
                log.warn("Cannot redirect to [{}] given the service is unauthorized to use CAS. "
                        + "Ensure the service is registered with CAS and is enabled to allow access", service);
            }
        } else if (StringUtils.isNotBlank(authorizedRedirectUrlFromRequest)) {
            WebUtils.putLogoutRedirectUrl(requestContext, authorizedRedirectUrlFromRequest);
        } else {
            log.debug("No target service is located for redirection after logout, or following service redirects is disabled");
        }
    }
}

 并且在H:\sso-server\src\main\resources\META-INF\spring.factories中添加加载

这样 就可以登出时候判断service跳转地址是不是自己想要的了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/624098.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

辞了外包,上岸字节测试岗我落泪了,400多个日夜没人知道我付出了多少....

前言&#xff1a; 没有绝对的天才&#xff0c;只有持续不断的付出。对于我们每一个平凡人来说&#xff0c;改变命运只能依靠努力幸运&#xff0c;但如果你不够幸运&#xff0c;那就只能拉高努力的占比。 2023年3月&#xff0c;我有幸成为了字节跳动的一名自动化测试工程师&am…

Qt导出pdf格式表格

预期目标如下&#xff1a; 头文件&#xff1a; #include #include #include #include #include #include #include private: QString m_html; 调用&#xff1a; QDateTime dateTime QDateTime::currentDateTime(); //当前日期和时间 QString ExportTime dateTime.t…

python带你获取小破站喜爱UP得所用内容

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 环境使用: Python 3.8 Pycharm 2022.3版本 ffmpeg <需要设置环境变量> 软件的使用 合成视频和音频 模块使用: 第三方模块&#xff0c;需要安装 import requests >>> pip install requests 内置模…

认识数据湖加速器(Data Lake Accelerator Goose FileSystem,GooseFS)

认识数据湖加速器Data Lake Accelerator Goose FileSystem&#xff0c;GooseFS 一、产品概述二、产品功能三、产品优势四、快速入门五、使用 GooseFS 预热 Table 中的数据六、使用 GooseFS 进行文件上传和下载操作七、使用 GooseFS 加速文件上传和下载操作八、关闭 GooseFS九、…

UE5 Chaos破碎系统学习2

本文继续从实用性的角度学习Chaos破碎系统&#xff0c;因为破碎的许多操作需要力场&#xff0c;比较麻烦&#xff0c;因此本文打算绕过力场实现一些效果&#xff1a; 1.显示材质效果 制作Chaos破碎效果时&#xff0c;会在编辑器下看不见材质&#xff0c;我们可以选择Geometr…

美创数据安全服务能力再获认可!

美创数据安全服务能力又一次获认可&#xff01; 近日&#xff0c;经全方位能力评估和专家评审&#xff0c;美创获得中国软件评测中心和中国计算机行业协会数据安全专业委员会联合颁发的《数据安全服务能力评定资格证书》&#xff0c;数据安全评估能力符合二级评定资格要求。 为…

生存压力下,Smartbi这套方案为企业降本增效带来新的希望

在如今的经济环境下&#xff0c;许多IT企业都面临着困境。经济的不景气导致市场竞争更加激烈&#xff0c;企业的盈利能力受到了严重的冲击&#xff1b;高昂的成本让企业喘不上气来。为了在这个艰难的时期生存下来&#xff0c;降本增效成为了企业的当务之急。 l实施项目利润低&a…

【C++】是内存管理,但C++ !! 模板初阶

目录 一&#xff0c;回望C语言内存 二&#xff0c; C 内存管理方式 1. 内置类型 2. 自定义类型 3. new & malloc 返回内容区别 4. operator new & operator delete 5. malloc/free和new/delete的区别总结 6. 定位new表达式(placement-new) &#xff08;了…

018+limou+C语言预处理

0.前言 您好&#xff0c;这里是limou3434的一篇博客&#xff0c;感兴趣您可以看看我的其他博文系列。本次我主要给您带来了C语言有关预处理的知识。 1.宏的深度理解与使用 1.1.数值宏常量 #define PI 3.1415926注意define和#之间是可以留有空格的 1.2.字符宏常量 #includ…

是德DSO9254A示波器/KEYSIGHT DSO9254A:2.5 GHz

KEYSIGHT是德DSO9254A示波器&#xff0c;Infiniium 9000 系列 2.5 GHz 示波器提供 4 个模拟通道、10 Mpts 存储器和 20 GSa/s 采样率。 简介 Keysight(原Agilent) Infiniium DSO9254A 配有 15 英寸 XGA 显示屏&#xff0c;而且包装非常轻巧&#xff0c;仅有 9 英寸深、26 磅重…

C++ 编写二维码(有源码)

首先来展示一下成果&#xff1a; 二维码图片好像违规了&#xff0c;直接给链接吧网址链接 如果你扫了这个二维码就会得到一个网址&#xff0c;该网址是我写代码的参考&#xff0c;该网站讲述了如何编写一个二维码&#xff0c;很详细&#xff0c;我没有实现汉字的编码&#xff…

LeetCode ! 42 Trapping Rain Water

参考资料&#xff1a;leetCode评论区大佬, 《程序员代码面试指南》 思路1&#xff1a;使用单调栈 维持一个从栈底到栈顶中的元素——下标&#xff0c;对应到数组是从大到小排序。 遍历数组&#xff0c;如果新值大于栈顶元素&#xff08;下标&#xff09;对应的数组值&#xf…

『Linux』第九讲:Linux多线程详解(六 - 完结)_ 线程池 | 读写锁

「前言」文章是关于Linux多线程方面的知识&#xff0c;上一篇是 Linux多线程详解&#xff08;五&#xff09;&#xff0c;今天这篇是 Linux多线程详解&#xff08;六&#xff09;&#xff0c;也是多线程最后一篇&#xff0c;内容大致是线程池&#xff0c;讲解下面开始&#xff…

什么?英语不好?这所211可以不考英语!

本期为大家整理热门院校“哈尔滨工程大学810”的择校分析&#xff0c;这个择校分析专题会为大家结合&#xff1a;初试复试占比、复试录取规则&#xff08;是否公平&#xff09;、往年录取录取名单、招生人数、分数线、专业课难度等进行分析。希望能够帮到大家! –所有数据来源…

KDJJC-80绝缘油介电强度测试仪

一、概述 测试仪&#xff08;单杯&#xff09;是我公司科研技术人员&#xff0c;依据国家标准GB507-1986及行标DL/T846.7-2004的有关规定&#xff0c;发挥自身优势&#xff0c;经过多次现场试验和长期不懈努力&#xff0c;精心研制开发的高准确度、数字化工业仪器。 为满足不同…

初步了解SpringCloud微服务架构

✅作者简介&#xff1a;大家好&#xff0c;我是Cisyam&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Cisyam-Shark的博客 &#x1f49e;当前专栏&#xff1a; 微服务探索之旅 ✨特色专…

Apikit SaaS 10.9.0 版本更新:接口测试支持通过 URL 请求大型文件,覆盖更多场景的文件请求测试

Hi&#xff0c;大家好&#xff01; Eolink Apikit 即将在 2023年 6月 8日晚 18:00 开始更新 10.9.0 版本。本次版本更新主要是对多个应用级资源合并&#xff0c;并基于此简化付费套餐和降低费率。 本次应用合并是为了接下来更好的发挥 Eolink Apikit 的优势&#xff0c;提供 …

Web前端-React学习

React基础 React 概述 React 是一个用于构建用户界面的JavaScript库。 用户界面&#xff1a; HTML页面&#xff08;前端&#xff09; React主要用来写HTML页面&#xff0c; 或构建Web应用 如果从MVC的角度来看&#xff0c;React仅仅是视图层&#xff08;V&#xff09;,也就…

多目标建模loss为什么最好同时收敛?

多目标的多个loss是否同时收敛最好&#xff1f; 假设 task A的独有参数 W a W_a Wa​task B的独有参数 W b W_b Wb​task A和 task B的共享的参数 W s W_s Ws​ 那么 l o s s l o s s a l o s s b loss loss_a loss_b losslossa​lossb​ 假设损失函数为 f f f&…

【DepthFilter】深度滤波器

14讲P326-327 函数实现一个深度滤波器&#xff0c;用于计算图像中某个像素点的深度值。算法步骤的含义和含义&#xff1a; 将当前帧的像素点和参考帧的像素点通过三角化计算深度。将参考帧到当前帧的变换矩阵 T_C_R 转换为当前帧到参考帧的变换矩阵 T_R_C。将参考帧像素点 pt_…