松哥整理的八个开源的 Spring Boot 学习资源

文章地址:跳转

Spring Boot 算是目前 Java 领域最火的技术栈了,松哥年初出版的 《Spring Boot + Vue 全栈开发实战》迄今为止已经加印了 3 次,Spring Boot 的受欢迎程度可见一斑。经常有人问松哥有没有推荐的 Spring Boot 学习资料?当然有!买松哥书就对了,哈哈。除了书呢?当然就是开源项目了,今天松哥整理了几个优质 Spring Boot 开源项目给大家参考,希望能够帮助到正在学习 Spring Boot 的小伙伴!
--------------------- 
作者:_江南一点雨 
来源:CSDN 
原文:https://blog.csdn.net/u012702547/article/details/90294784 
版权声明:本文为博主原创文章,转载请附上博文链接!

 

附:其他项目资源 

给大家推荐8个 SpringBoot 精选项目

七个开源的 Spring Boot 前后端分离项目,一定要收藏!

10 个开源项目

ruoyi

FH Admin

 

欢迎扫码关注公众号:Stephen,一起学习,一起成长!

 

 

<think>我们正在讨论SpringBoot集成CAS单点登录,并获取用户信息。根据之前的引用,我们可以知道CAS单点登录的基本概念和SpringBoot集成CAS的基本步骤。现在用户特别关注如何获取用户信息,这通常发生在CAS认证成功后,在客户端应用中需要获取已登录用户的信息。在CAS单点登录流程中,当用户通过CAS服务器认证后,会重定向回客户端应用,并携带一个ticket。客户端应用需要验证这个ticket,并从CAS服务器获取用户信息(即断言Assertion)。在SpringBoot应用中,我们可以通过配置CAS客户端来获取这些信息。根据引用[3],我们主要需要实现`UserDetailsService`接口,但获取用户信息不仅仅是通过数据库查询,还可以直接从CAS返回的信息中获取。不过,通常CAS服务器返回的是用户名,而用户的详细信息可能需要从数据库或其他存储中获取。但是,CAS也可以返回一些属性(attributes),这些属性可以包含用户信息。因此,获取用户信息有两种常见方式:1.直接从CAS服务器返回的断言(Assertion)中获取属性(attributes)。2.通过用户名(从断言中获取)查询数据库获取用户详细信息。下面,我们将分别讨论这两种方式,并给出示例代码。首先,我们需要在SpringBoot项目中集成CAS客户端。根据引用[2]和[3],我们需要添加相关依赖。这里我们主要关注获取用户信息,所以假设已经完成了基本的CAS集成。步骤:1.添加依赖(引用[3]中提到的依赖,以及CAS客户端依赖)2.配置CAS客户端3.获取用户信息具体实现:一、依赖在`pom.xml`中添加CAS客户端依赖(注意:这里使用的是SpringSecurityCAS模块):```xml<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-cas</artifactId></dependency>```二、配置CAS客户端在`application.properties`中配置CAS服务器和客户端信息:```properties#CAS服务器地址cas.server.url=https://cas.example.com/cas#当前应用的地址(客户端地址)cas.client.url=https://localhost:8443#登录地址security.cas.login=${cas.server.url}/login#验证ticket的地址security.cas.validation=${cas.server.url}/serviceValidate```三、配置SpringSecurity以使用CAS创建一个配置类,继承`WebSecurityConfigurerAdapter`,并配置CAS认证流程。四、获取用户信息方式1:从CAS断言中获取属性在SpringSecurity中,认证成功后,用户信息会存储在`Authentication`对象中。我们可以通过`SecurityContextHolder`获取。但是,默认情况下,CAS认证成功后,`Authentication`对象的主体(Principal)是一个`CasAssertionAuthenticationToken`,它包含了从CAS服务器返回的断言(Assertion),断言中包含了用户属性。例如,我们可以这样获取:```javaAuthenticationauthentication=SecurityContextHolder.getContext().getAuthentication();if(authentication!=null&&authentication.getPrincipal()instanceofCasAssertionAuthenticationToken){CasAssertionAuthenticationTokencasToken=(CasAssertionAuthenticationToken)authentication.getPrincipal();Assertionassertion=casToken.getAssertion();//从断言中获取用户名Stringusername=assertion.getPrincipal().getName();//获取属性Map<String,Object>attributes=assertion.getPrincipal().getAttributes();//例如,获取emailStringemail=(String)attributes.get("email");//...其他属性}```方式2:通过用户名查询数据库如果我们需要更详细的用户信息,比如角色、权限等,通常需要查询数据库。这时,我们可以实现`UserDetailsService`接口,并在其中根据用户名从数据库中加载用户信息。在配置CAS时,我们可以指定一个`UserDetailsService`:```java@Configuration@EnableWebSecuritypublicclassSecurityConfigextendsWebSecurityConfigurerAdapter{@AutowiredprivateUserDetailsServiceuserDetailsService;@Overrideprotectedvoidconfigure(HttpSecurityhttp)throwsException{http.authorizeRequests().anyRequest().authenticated().and().exceptionHandling().authenticationEntryPoint(casAuthenticationEntryPoint()).and().logout().logoutUrl("/logout").logoutSuccessUrl("/").and().addFilter(casAuthenticationFilter()).addFilterBefore(casLogoutFilter(),LogoutFilter.class).addFilterBefore(singleSignOutFilter(),CasAuthenticationFilter.class);}@BeanpublicCasAuthenticationEntryPointcasAuthenticationEntryPoint(){CasAuthenticationEntryPointentryPoint=newCasAuthenticationEntryPoint();entryPoint.setLoginUrl("https://cas.example.com/cas/login");entryPoint.setServiceProperties(serviceProperties());returnentryPoint;}@BeanpublicServicePropertiesserviceProperties(){ServicePropertiesproperties=newServiceProperties();properties.setService("https://localhost:8443/login/cas");properties.setSendRenew(false);returnproperties;}@BeanpublicCasAuthenticationFiltercasAuthenticationFilter()throwsException{CasAuthenticationFilterfilter=newCasAuthenticationFilter();filter.setAuthenticationManager(authenticationManager());returnfilter;}@BeanpublicAuthenticationProvidercasAuthenticationProvider(){CasAuthenticationProviderprovider=newCasAuthenticationProvider();provider.setServiceProperties(serviceProperties());provider.setTicketValidator(cas20ServiceTicketValidator());provider.setAuthenticationUserDetailsService(authenticationUserDetailsService());provider.setKey("CAS_PROVIDER_LOCALHOST_8443");returnprovider;}@BeanpublicCas20ServiceTicketValidatorcas20ServiceTicketValidator(){returnnewCas20ServiceTicketValidator("https://cas.example.com/cas");}@BeanpublicUserDetailsByNameServiceWrapper<CasAssertionAuthenticationToken>authenticationUserDetailsService(){returnnewUserDetailsByNameServiceWrapper<>(userDetailsService);}//其他配置:单点登出等}```其中,`UserDetailsService`的实现类需要从数据库加载用户信息:```java@ServicepublicclassUserDetailsServiceImplimplementsUserDetailsService{@AutowiredprivateUserRepositoryuserRepository;@OverridepublicUserDetailsloadUserByUsername(Stringusername)throwsUsernameNotFoundException{Useruser=userRepository.findByUsername(username);if(user==null){thrownewUsernameNotFoundException("Usernotfound");}//假设User类实现了UserDetails接口,或者使用SpringSecurity的User类returnneworg.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),user.getAuthorities());}}```这样,在认证成功后,`SecurityContextHolder`中存储的`Authentication`对象的主体(Principal)将是我们从数据库加载的`UserDetails`对象。总结:获取用户信息的方式取决于我们的需求。如果CAS服务器返回的属性已经足够,我们可以直接从断言中获取;如果需要更详细的用户信息,则应该通过实现`UserDetailsService`来从数据库加载。注意:在CAS流程中,客户端应用在验证ticket后,CAS服务器会返回一个包含用户名的断言,以及可能的其他属性。这些属性需要在CAS服务器端配置(如LDAP或数据库中的属性释放策略)。下面,我们根据上述内容生成相关问题。</think>### Spring Boot 集成 CAS 单点登录获取用户信息教程 在 Spring Boot 中集成 CAS 单点登录并获取用户信息,主要分为以下步骤: #### 1. **添加核心依赖** 在 `pom.xml` 中添加 CAS 客户端和 Spring Security 依赖: ```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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> ``` #### 2. **配置 CAS 客户端** 在 `application.properties` 中配置: ```properties # CAS 服务器配置 cas.server.url=https://cas.example.com/cas cas.server.login-url=${cas.server.url}/login cas.server.logout-url=${cas.server.url}/logout # 客户端配置 cas.client.url=https://localhost:8443 cas.client.login=/login/cas cas.client.logout=/logout/cas # 数据库配置(用于存储用户信息) spring.datasource.url=jdbc:mysql://localhost:3306/sso_db spring.datasource.username=root spring.datasource.password=123456 spring.jpa.hibernate.ddl-auto=update ``` #### 3. **实现用户信息获取** ##### (1) 从 CAS 断言直接获取属性 在控制器中通过 `SecurityContextHolder` 获取用户信息: ```java import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.cas.authentication.CasAuthenticationToken; @RestController public class UserController { @GetMapping("/userinfo") public Map<String, Object> getUserInfo() { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth instanceof CasAuthenticationToken) { CasAuthenticationToken casToken = (CasAuthenticationToken) auth; // 获取 CAS 返回的属性 Map<String, Object> attributes = casToken.getAssertion().getPrincipal().getAttributes(); return attributes; // 返回如 {email: "[email protected]", name: "John"} } return Collections.singletonMap("error", "未认证"); } } ``` ##### (2) 通过数据库查询用户详情 实现 `UserDetailsService` 接口: ```java @Service public class CasUserDetailsService implements UserDetailsService { @Autowired private UserRepository userRepository; // JPA 仓库 @Override public UserDetails loadUserByUsername(String username) { User user = userRepository.findByUsername(username) .orElseThrow(() -> new UsernameNotFoundException("用户不存在")); // 返回包含权限信息的用户对象 return new org.springframework.security.core.userdetails.User( user.getUsername(), "", // CAS 无需密码 AuthorityUtils.createAuthorityList("ROLE_USER") ); } } ``` #### 4. **配置 Spring Security** ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CasUserDetailsService casUserDetailsService; @Value("${cas.server.login-url}") private String casLoginUrl; @Value("${cas.client.url}") private String clientUrl; @Bean public ServiceProperties serviceProperties() { ServiceProperties sp = new ServiceProperties(); sp.setService(clientUrl + "/login/cas"); sp.setSendRenew(false); // 非强制重新登录 return sp; } @Bean public CasAuthenticationFilter casAuthenticationFilter() throws Exception { CasAuthenticationFilter filter = new CasAuthenticationFilter(); filter.setServiceProperties(serviceProperties()); filter.setAuthenticationManager(authenticationManager()); return filter; } @Bean public CasAuthenticationProvider casAuthenticationProvider() { CasAuthenticationProvider provider = new CasAuthenticationProvider(); provider.setServiceProperties(serviceProperties()); provider.setTicketValidator(cas30ServiceTicketValidator()); provider.setAuthenticationUserDetailsService(casUserDetailsService); provider.setKey("CAS_PROVIDER_KEY"); return provider; } @Bean public Cas30ServiceTicketValidator cas30ServiceTicketValidator() { return new Cas30ServiceTicketValidator(casLoginUrl); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/userinfo").authenticated() .anyRequest().permitAll() .and() .logout().logoutSuccessUrl("/") .and() .csrf().disable(); } } ``` #### 5. **测试验证** 1. 访问客户端受保护端点(如 `/userinfo`) 2. 重定向到 CAS 登录页 3. 登录成功后回调到客户端 4. 控制器返回 JSON 格式的用户属性: ```json { "email": "[email protected]", "name": "John Doe", "department": "IT" } ``` > **关键点说明** > - CAS 服务器需预先配置属性释放策略(如 LDAP 属性映射) > - 客户端通过 `CasAuthenticationToken` 直接获取 CAS 返回的属性 > - 数据库查询适用于需要补充本地存储信息的场景[^3] --- ### 相关问题 1. **如何配置 CAS 服务器释放自定义用户属性?** > 需在 CAS 服务器的 `attributeRepository` 配置中定义属性释放规则,例如从 LDAP 中映射邮箱/部门等字段[^1]。 2. **Spring Security 中如何处理 CAS 单点登出?** > 需配置 `SingleSignOutFilter` 和 `LogoutFilter`,监听 CAS 的登出请求并销毁本地会话[^4]。 3. **CAS 集成后如何实现基于角色的权限控制?** > 可在 `UserDetailsService` 实现中查询数据库角色,并在 `HttpSecurity` 配置中使用 `.hasRole("ADMIN")` 进行拦截。 4. **CAS 客户端如何验证服务票据(Service Ticket)?** > 通过 `Cas30ServiceTicketValidator` 向 CAS 服务器发送 `/serviceValidate` 请求验证票据有效性[^3]。 5. **多系统集成时如何避免重复登录?** > 确保所有子系统使用相同的 CAS 服务器域名,浏览器携带 TGC(Ticket Granting Cookie)实现单点登录[^2]。 [^1]: 手把手教你入门 Spring Boot + CAS 单点登录 [^2]: Spring Boot 集成 Shiro 和 CAS 单点登录教程 [^3]: Java教程:Spring Boot+CAS 单点登录,如何对接数据库? [^4]: spring boot 集成cas单点登录
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值