CAS单点登录-集成客户端springboot方式(八)

本文详细介绍如何在SpringBoot项目中接入CAS认证服务,包括环境搭建、服务端配置、客户端接入流程及测试验证,适用于多服务认证场景。

之前在服务端整合了数据库,也完成的动态service配置,我们一直在操作cas服务器端,这里我们就来使用springboot完成cas客户端的接入操作。

环境概述

ip端口对应服务
127.0.0.18443CAS服务器
127.0.0.19001CAS客户端1
127.0.0.19002CAS客户端2

service配置(服务端)

客户端接入 CAS 首先需要在服务端进行注册,否则客户端访问将提示“未认证授权的服务”警告:


11464886-b5b8811cdb1f75aa.png

为了方便后面测试,我们这里对所有https和http请求的service进行允许认证,在resources/services下新建文件HTTPS_HTTP-10000001.json,这个文件是我从cas源代码同路径下拷贝过来的。

{
  "@class" : "org.apereo.cas.services.RegexRegisteredService",
  "serviceId" : "^(https|imaps|http)://.*",
  "name" : "测试客户端",
  "id" : 100002,
  "description" : "这是一个测试客户端的服务,所有的https或者http访问都允许通过",
  "evaluationOrder" : 2
}

注意:
services目录中可包含多个 JSON 文件,其命名必须满足以下规则:${name}-${id}.json,id必须为json文件中内容id一致。
对其中属性的说明如下,更多详细内容见官方文档-Service-Management。

  • @class:必须为org.apereo.cas.services.RegisteredService的实现类
  • serviceId:对服务进行描述的表达式,可用于匹配一个或多个 URL 地址
  • name: 服务名称
  • id:全局唯一标志
  • description:服务描述,会显示在默认登录页
  • evaluationOrder:定义多个服务的执行顺序

application.properties:

##
# service 注册配置
#
#开启识别json文件,默认false
cas.serviceRegistry.initFromJson=true

#自动扫描服务配置,默认开启
#cas.serviceRegistry.watcherEnabled=true
#120秒扫描一遍
#cas.serviceRegistry.repeatInterval=120000
#延迟15秒开启
#cas.serviceRegistry.startDelay=15000

#默认json/yml资源加载路径为resources/services
#cas.serviceRegistry.config.location=classpath:/services

启动cas-server

启动信息中如果发现下图日志表示注册成功


11464886-b5104981247d400b.png

同时由于我们配置了mysql数据库动态service,系统会自动见json中的service同步到数据库中:


11464886-fdf962708950ba71.png

客户端配置

  1. 新建cas-client1客户端工程
    具体步骤这里就不详细说明

  2. 引入cas-client依赖
    这里引入别人写好的cas-client-autoconfig-support的starter类,当前最新版:2.3.0-GA

<dependency>
    <groupId>net.unicon.cas</groupId>
    <artifactId>cas-client-autoconfig-support</artifactId>
    <version>2.3.0-GA</version>      
</dependency>
  1. 配置CAS服务器和客户端地址
#cas配置
#cas服务端前缀,不是登录地址
cas.server-url-prefix=http://localhost:8443/cas
#cas的登录地址
cas.server-login-url=http://localhost:8443/cas/login
#当前客户端的地址
cas.client-host-url=http://localhost:9001
#Ticket校验器使用Cas30ProxyReceivingTicketValidationFilter
cas.validation-type=CAS3
  1. 开启CAS Client支持
@SpringBootApplication
@EnableCasClient//开启cas
public class Client1Application {

    public static void main(String[] args) {
        SpringApplication.run(Client1Application.class, args);
    }
}
  1. 编程测试Controller
@RestController
public class UserController {

    @GetMapping("/hello")
    public String hello() {
        return "恭喜CAS客户端整合成功";
    }
}

  1. 浏览器输入:http://localhost:9001/hello, 系统没有登陆会自动重定向到cas服务端登陆页面
11464886-4ab2471f1d9df1c4.png
image.png
  1. 输入:admin/123456 登陆后,会重定向会目标路径


    11464886-4cc0b8184205dc7a.png

注意:如果引入https必须保证客户端证书和服务端证书是同一个证书,不然就会报错。

sudo keytool -import -file /Users/wangsaichao/Desktop/tomcat.cer -alias tomcat -keystore %JAVA_HOME%/jre/lib/security/cacerts -storepass changeit

CAS单点登录集成到Spring Boot和React项目中,可以按以下步骤进行: ### Spring Boot后端集成 #### 1. 添加依赖 在`pom.xml`中添加Spring Security和Spring Security CAS的依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-cas</artifactId> </dependency> ``` 此步骤参考了引用中添加依赖的示例[^3]。 #### 2. 配置`application.properties` 配置CAS相关的参数,示例如下: ```properties # 单点登录前缀 cas.server-url-prefix=http://cas.server.com:8443/cas # 单点登录路径 cas.server-login-url=http://cas.server.com:8443/cas/login cas.client-host-url=http://127.0.0.1:8088 cas.use-session=true cas.validation-type=cas server.port=8088 # 自定义项目后台单点登录接口路径 client-host-url=http://127.0.0.1:8088/test/login/ssologin # 自定义项目前台单点登录接口路径-单点登录平台也是配置此路径 adminPath=http://127.0.0.1:9003/ssologin ``` 这里的配置参考了引用中的配置示例,用于指定CAS服务器的地址、登录路径以及客户端的相关信息[^2]。 #### 3. 配置Spring Security 创建一个配置类来配置Spring Security以使用CAS进行身份验证。示例代码如下: ```java import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.cas.authentication.CasAuthenticationProvider; import org.springframework.security.cas.web.CasAuthenticationEntryPoint; import org.springframework.security.cas.web.CasAuthenticationFilter; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.web.authentication.logout.LogoutFilter; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Value("${cas.server-url-prefix}") private String casServerUrlPrefix; @Value("${cas.server-login-url}") private String casServerLoginUrl; @Value("${cas.client-host-url}") private String casClientHostUrl; @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .exceptionHandling() .authenticationEntryPoint(casAuthenticationEntryPoint()) .and() .addFilter(casAuthenticationFilter()) .addFilterBefore(logoutFilter(), LogoutFilter.class); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(casAuthenticationProvider()); } @Bean public CasAuthenticationEntryPoint casAuthenticationEntryPoint() { CasAuthenticationEntryPoint entryPoint = new CasAuthenticationEntryPoint(); entryPoint.setLoginUrl(casServerLoginUrl); entryPoint.setServiceProperties(serviceProperties()); return entryPoint; } @Bean public CasAuthenticationFilter casAuthenticationFilter() throws Exception { CasAuthenticationFilter filter = new CasAuthenticationFilter(); filter.setAuthenticationManager(authenticationManager()); return filter; } @Bean public CasAuthenticationProvider casAuthenticationProvider() { CasAuthenticationProvider provider = new CasAuthenticationProvider(); provider.setServiceProperties(serviceProperties()); provider.setTicketValidator(cas30ServiceTicketValidator()); provider.setUserDetailsService(userDetailsService()); provider.setKey("casProviderKey"); return provider; } @Bean public ServiceProperties serviceProperties() { ServiceProperties serviceProperties = new ServiceProperties(); serviceProperties.setService(casClientHostUrl + "/j_spring_cas_security_check"); serviceProperties.setSendRenew(false); return serviceProperties; } @Bean public Cas30ServiceTicketValidator cas30ServiceTicketValidator() { return new Cas30ServiceTicketValidator(casServerUrlPrefix); } @Bean public UserDetailsService userDetailsService() { return new InMemoryUserDetailsManager(); } @Bean public LogoutFilter logoutFilter() { String logoutRedirectUrl = casServerUrlPrefix + "/logout?service=" + casClientHostUrl; LogoutFilter logoutFilter = new LogoutFilter(logoutRedirectUrl, new SecurityContextLogoutHandler()); logoutFilter.setFilterProcessesUrl("/logout"); return logoutFilter; } } ``` 此代码实现了Spring Security与CAS集成,包括配置认证入口点、认证过滤器和认证提供者等。 ### React前端集成 #### 1. 创建CAS客户端 导航到“Clients”→“Create”,输入Client ID(如“spring - boot - app”),选择Client Protocol为“openid - connect”,然后点击“Save”,此步骤参考了创建客户端的相关引用[^4]。 #### 2. 处理重定向 在前端代码中处理重定向逻辑。当用户未登录时,将用户重定向到CAS登录页面,登录成功后再重定向回前端页面。示例代码如下: ```jsx import React, { useEffect } from 'react'; import { useHistory } from 'react-router-dom'; const App = () => { const history = useHistory(); useEffect(() => { // 检查用户是否登录 const isLoggedIn = localStorage.getItem('isLoggedIn'); if (!isLoggedIn) { // 重定向到CAS登录页面 window.location.href = 'http://cas.server.com:8443/cas/login?service=http://127.0.0.1:9003/ssologin'; } }, []); return ( <div> {/* 页面内容 */} </div> ); }; export default App; ``` 此代码在组件挂载时检查用户是否登录,如果未登录则重定向到CAS登录页面。 ### 解决前后端重定向问题 前后端分离项目中,需要解决前后端重定向的问题。在打开前端页面时,如果用户未登录,要跳转到登录页面,登录成功后,再重定向到前端页面。这是单点登录成功的关键,如引用中所提到的,解决了此问题基本意味着单点登录成功[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值