Spring Security系列教程28--Spring Security实现CAS单点登录下篇--搭建CAS客户端

简介: 前言在上一章节中,一一哥 带各位搭建了CAS Server端项目,也就是我们构建了一个统一的单点登录认证中心,接下来就可以搭建CAS客户端项目,然后实现客户端与服务端之间的交互认证,从而完成单点登录。接下来各位就跟着 壹哥 搭建CAS客户端,最终把单点登录实现出来吧!一. 搭建CAS客户端1. 创建新项目我们在之前的Spring Security项目中,创建一个新的module模块,作为CAS Client项目,如下图。2. 引入依赖然后在这个模块的pom.xml文件中,引入相关依赖。 <dependencies> <dependency>

前言

在上一章节中,一一哥 带各位搭建了CAS Server端项目,也就是我们构建了一个统一的单点登录认证中心,接下来就可以搭建CAS客户端项目,然后实现客户端与服务端之间的交互认证,从而完成单点登录。

接下来各位就跟着 壹哥 搭建CAS客户端,最终把单点登录实现出来吧!

一. 搭建CAS客户端

1. 创建新项目

我们在之前的Spring Security项目中,创建一个新的module模块,作为CAS Client项目,如下图。

2. 引入依赖

然后在这个模块的pom.xml文件中,引入相关依赖。

 

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-web</artifactId></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-cas</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>

其中最主要的依赖是spring-security-cas,其内部依赖关系如下:

3. 配置CAS Client

创建一个application.yml文件,在其中添加CAS Client相关的配置,主要是与CAS Server进行关联的配置,这里请填写自己CAS Server端的地址信息。

cas:#对服务端进行配置  server:#cas server的主路径,这里指向我们的cas服务端    prefix: https://cas.yyg.cn:8443/cas
#指向cas服务端的登录页面    login: ${cas.server.prefix}/login
#指向cas服务端的退出登录页面    logout: ${cas.server.prefix}/logout
#对客户端进行配置    client:#配置cas客户端url前缀    prefix: http://client.cas.yyg.cn:8080#配置客户端登录地址    login: ${cas.client.prefix}/login/cas
#以相对路径的形式配置退出登录接口    relative: /logout/cas
#以绝对路径的形式配置退出登录接口    logout: ${cas.client.prefix}${cas.client.relative}  user:#配置登录到cas服务端的用户名    inmemory: yyg

4. 创建配置类

在上一小节中我已经创建了CAS Client相关的配置信息,为了方便我们进行配置信息的引用,我们可以创建一个与之对应的配置类CasSecurityConfig,并且在这个类中,我们再创建一些单点登录相关的过滤器。

@ConfigurationpublicclassCasSecurityConfig {
@Value("${cas.server.prefix}")
privateStringcasServerPrefix;
@Value("${cas.server.login}")
privateStringcasServerLogin;
@Value("${cas.server.logout}")
privateStringcasServerLogout;
@Value("${cas.client.login}")
privateStringcasClientLogin;
@Value("${cas.client.logout}")
privateStringcasClientLogout;
@Value("${cas.client.relative}")
privateStringcasClientLogoutRelative;
@Value("${cas.user.inmemory}")
privateStringcasUserInMemory;
/*** 配置CAS Client的属性** @return*/@BeanpublicServicePropertiesserviceProperties() {
ServicePropertiesserviceProperties=newServiceProperties();
// 与CasAuthenticationFilter监视的URL一致serviceProperties.setService(casClientLogin);
// 是否关闭单点登录,默认为false,所以也可以不设置。serviceProperties.setSendRenew(false);
returnserviceProperties;
    }
/*** 配置CAS认证入口,提供用户浏览器重定向的地址** @param sp* @return*/@Bean@PrimarypublicAuthenticationEntryPointauthenticationEntryPoint(ServicePropertiessp) {
CasAuthenticationEntryPointentryPoint=newCasAuthenticationEntryPoint();
// CAS Server认证的登录地址entryPoint.setLoginUrl(casServerLogin);
entryPoint.setServiceProperties(sp);
returnentryPoint;
    }
/*** 配置ticket校验功能,需要提供CAS Server校验ticket的地址** @return*/@BeanpublicTicketValidatorticketValidator() {
// 默认情况下使用Cas20ProxyTicketValidator,验证入口是${casServerPrefix}/proxyValidatereturnnewCas20ProxyTicketValidator(casServerPrefix);
    }
/*** 在内存中创建一个用户并分配权限** @return*/@BeanpublicUserDetailsServiceuserDetailsService() {
InMemoryUserDetailsManagermanager=newInMemoryUserDetailsManager();
manager.createUser(User.withUsername(casUserInMemory).password("").roles("USER").build());
returnmanager;
    }
/*** 设置cas认证处理逻辑** @param sp* @param ticketValidator* @param userDetailsService* @return*/@BeanpublicCasAuthenticationProvidercasAuthenticationProvider(ServicePropertiessp, TicketValidatorticketValidator, UserDetailsServiceuserDetailsService) {
CasAuthenticationProviderprovider=newCasAuthenticationProvider();
provider.setServiceProperties(sp);
provider.setTicketValidator(ticketValidator);
provider.setUserDetailsService(userDetailsService);
provider.setKey("yyg");
returnprovider;
    }
/*** 提供CAS认证专用过滤器,过滤器的认证逻辑由CasAuthenticationProvider提供** @param sp* @param ap* @return*/@BeanpublicCasAuthenticationFiltercasAuthenticationFilter(ServicePropertiessp, AuthenticationProviderap) {
CasAuthenticationFilterfilter=newCasAuthenticationFilter();
filter.setServiceProperties(sp);
filter.setAuthenticationManager(newProviderManager(Arrays.asList(ap)));
returnfilter;
    }
/*** 配置单点登录过滤器,接受cas服务端发出的注销请求** @return*/@BeanpublicSingleSignOutFiltersingleSignOutFilter() {
SingleSignOutFiltersingleSignOutFilter=newSingleSignOutFilter();
singleSignOutFilter.setCasServerUrlPrefix(casServerPrefix);
singleSignOutFilter.setIgnoreInitConfiguration(true);
returnsingleSignOutFilter;
    }
/*** 将注销请求转发到cas server** @return*/@BeanpublicLogoutFilterlogoutFilter() {
LogoutFilterlogoutFilter=newLogoutFilter(casServerLogout, newSecurityContextLogoutHandler());
// 设置客户端注销请求的路径logoutFilter.setFilterProcessesUrl(casClientLogoutRelative);
returnlogoutFilter;
    }
}

5. 创建Security配置类

然后创建一个WebSecurityConfig配置类,进行相关接口的认证拦截,并配置单点登录相关的过滤器。

@EnableWebSecurity(debug=true)
publicclassWebSecurityConfigextendsWebSecurityConfigurerAdapter {
@AutowiredprivateAuthenticationProviderauthenticationProvider;
@AutowiredprivateAuthenticationEntryPointentryPoint;
@AutowiredprivateCasAuthenticationFiltercasAuthenticationFilter;
@AutowiredprivateSingleSignOutFiltersingleSignOutFilter;
@AutowiredprivateLogoutFilterrequestSingleLogoutFilter;
@Overrideprotectedvoidconfigure(AuthenticationManagerBuilderauth) {
auth.authenticationProvider(authenticationProvider);
    }
@Overrideprotectedvoidconfigure(HttpSecurityhttp) throwsException {
http.authorizeRequests()
                .antMatchers("/admin/**")
                .hasRole("ADMIN")
                .antMatchers("/user/**")
                .hasRole("USER")
                .antMatchers("/login/cas", "/favicon.ico", "/error")
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .exceptionHandling()
//设置认证入口                .authenticationEntryPoint(entryPoint)
                .and()
//添加过滤器,执行单点登录处理逻辑                .addFilter(casAuthenticationFilter)
//处理认证逻辑                .addFilterBefore(singleSignOutFilter, CasAuthenticationFilter.class)
//处理退出登录                .addFilterBefore(requestSingleLogoutFilter, LogoutFilter.class);
    }
}

6. 创建测试接口

接下来创建一个UserController,进行测试。根据前面的WebSecurityConfig配置类可知,这个/user接口要求访问者必须具有user角色权限才能访问,所以是一种受保护的资源。

@RestController@RequestMapping("/user")
publicclassUserController {
@GetMappingpublicStringhello() {
return"hello, user";
    }
}

7. 创建项目入口类

/*** cas客户端,实现与cas服务端的认证*/@SpringBootApplicationpublicclassDemo13Application {
publicstaticvoidmain(String[] args) {
SpringApplication.run(Demo13Application.class, args);
    }
}

8. Client项目结构

至此,我已经把CAS Client项目核心代码都已经编写完毕,你可以仿照我这个项目创建流程,创建多个CAS Client项目。CAS Server项目只有一个,CAS Client项目可以有多个。

整个项目的代码结构如下:

9. 启动运行项目

接下来我们把这个客户端项目启动运行,进行接口测试,看看能不能在未登录时,跳转到CAS Server进行统一的认证。

我们直接在浏览器中输入http://client.cas.yyg.cn:8080/user地址,这个地址是我们CAS Client客户端项目中定义的测试接口,必须具有user角色权限才能访问,未登录时是不能直接访问的。

在我们输入http://client.cas.yyg.cn:8080/user地址后,在浏览器控制台,我们可以发现访问该接口时产生了一个302重定向,会从/user接口重定向到了CAS Server的/cas/login登录界面,这里需要我们输入之前在CAS Server的application.properties配置文件中配置的用户名和密码,yyg:123

当我们输入正确的用户名和密码,CAS Server认证成功后,就会重新从CAS Server端重定向回到CAS Client端,从而实现对/user接口的访问。

这样就实现了CAS Client与CAS Server端之间的交互认证。

二. 单点注销

在实现了单点登录之后,接下来我们还可以实现单点注销。

这时候我们可以通过请求https://cas.yyg.cn:8443/cas/logout地址,来执行单点注销,这样当一个CAS客户端项目退出后,CAS Server中其他所有的客户端也都注销了。

至此,壹哥 就带大家简单的实现了基于CAS框架的单点登录和单点注销。我们利用CAS Server作为一个统一的中央认证中心,然后创建若干个CAS Client项目,就实现了单点登录的需求。

你学会了吗?如果觉得本系列文章对你有帮助,请在评论区点赞好评哦!

相关文章
|
21天前
|
XML 安全 前端开发
Spring Security 重点解析(下)
Spring Security 重点解析
40 1
|
21天前
|
安全 Java 数据安全/隐私保护
|
21天前
|
安全 NoSQL Java
Spring Security 重点解析(上)
Spring Security 重点解析
35 1
|
1天前
|
安全 Java 数据安全/隐私保护
用Spring Security快速实现 RBAC模型案例
RBAC模型是一种常见的权限管理机制,它将权限赋予角色而非用户,用户通过角色获取权限。主要组件包括用户、角色、权限、会话、角色分配和权限分配。RBAC简化了权限管理,方便权限变更,常用于大型组织。
|
21天前
|
Java 测试技术 API
Spring Boot 单元测试 0基础教程
Spring Boot 单元测试 0基础教程
16 0
|
21天前
|
Java 关系型数据库 MySQL
优质全套Spring全套教程三
优质全套Spring全套教程三
|
21天前
|
XML Java 数据格式
优质全套Spring全套教程二
优质全套Spring全套教程二
|
21天前
|
XML Java 数据格式
优质全套Spring全套教程一
优质全套Spring全套教程一
|
21天前
|
存储 安全 Java
第10章 Spring Security 的未来趋势与高级话题(2024 最新版)(下)
第10章 Spring Security 的未来趋势与高级话题(2024 最新版)
29 2
|
21天前
|
安全 Cloud Native Java
第10章 Spring Security 的未来趋势与高级话题(2024 最新版)(上)
第10章 Spring Security 的未来趋势与高级话题(2024 最新版)
35 2