使用Springboot搭建cas客户端,主要是配置四个过滤器和一个监听器。
单点登录
创建过滤器类
用于过滤不需要登录的用户,需要实现UrlPatternMatcherStrategy 接口,在matches 函数里添加不需要用户登录的链接。
package com.zhang.springbootcasclient1.auth;
import org.jasig.cas.client.authentication.UrlPatternMatcherStrategy;
import java.util.regex.Pattern;
/**
* @Auther: zhang
* @Date: 2018/8/30 09:46
* @Description:过滤掉不需要授权登录的页面
*/
public class SimpleUrlPatternMatcherStrategy implements UrlPatternMatcherStrategy{
private Pattern pattern;
/**
* description:判断是否匹配这个字符串
* @param: [url]用户请求的连接
* @return: true:不需要拦截
* false:必须要登录
*/
@Override
public boolean matches(String url) {
//使用正则表达式来匹配需要忽略的连接
return this.pattern.matcher(url).find();
}
/**
* description:正则表达式的规则,该规则在配置AuthenticationFilter的ignorePattern中设置
* @param: [pattern]
* @return: void
*/
@Override
public void setPattern(String pattern) {
this.pattern = Pattern.compile(pattern);
}
}
创建首页控制器
package com.zhang.springbootcasclient1.controller;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.validation.Assertion;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.Map;
/**
* @Auther: zhangll
* @Date: 2018/8/30 10:11
* @Description:
*/
@Controller
public class IndexController {
@RequestMapping(value={"/", "/index"})
public String index(HttpServletRequest request) {
//获取cas给我们传递回来的对象,这个对象在Session中
//session的 key是 CONST_CAS_ASSERTION
Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
Principal principal = assertion.getPrincipal();
String loginName =principal.getName();
System.out.printf("登录用户名:%s\r\n",loginName);
System.out.printf("ValidFromDate:%s\r\n",assertion.getValidFromDate());
System.out.printf("ValidUntilDate:%s\r\n",assertion.getValidUntilDate());
System.out.printf("AuthenticationDate:%s\r\n",assertion.getAuthenticationDate());
//获取自定义返回值的数据
if (principal instanceof AttributePrincipal) {
//cas传递过来的数据
Map result =( (AttributePrincipal)principal).getAttributes();
for(Map.Entry entry :result.entrySet()) {
String key = entry.getKey();
Object val = entry.getValue();
System.out.printf("%s:%s\r\n",key,val);
}
}
return "index";
}
}
首页代码
Title
当前所在子系统:测试系统1
系统1
系统2
Authenticated User Id:
退出系统(默认退出页面)
退出系统(定制退出页面)
用户退出控制器
package com.zhang.springbootcasclient1.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
/**
* @Auther: zhangll
* @Date: 2018/8/30 11:35
* @Description:
*/
@Controller
public class LogoutController {
@RequestMapping("/logoutDefault")
public String logout1(HttpSession session) {
session.invalidate();
// 直接退出,走默认退出方式
return "redirect:https://casserver.com:8443/logout";
}
@RequestMapping("/logoutCustom")
public String logout2(HttpSession session) {
session.invalidate();
// 退出登录后,跳转到退出成功的页面,不走默认页面
return "redirect:https://casserver.com:8443/logout?service=http://springbootcasclient.com:8001/logout/success";
}
@RequestMapping("/logout/success")
@ResponseBody
public String logout2() {
return "系统1注销成功";
}
}
配置过滤器到springboot
package com.zhang.springbootcasclient1;
import org.jasig.cas.client.authentication.AuthenticationFilter;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
import org.jasig.cas.client.util.HttpServletRequestWrapperFilter;
import org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import java.util.EventListener;
import java.util.HashMap;
import java.util.Map;
@SpringBootApplication
public class SpringbootCasClient1Application {
private static final String CAS_SERVER_URL_PREFIX = "https://casserver.com:8443/";
private static final String CAS_SERVER_URL_LOGIN = "https://casserver.com:8443/login";
//本机的名称
private static final String SERVER_NAME = "http://springbootcasclient.com:8001/";
/**
* description: 登录过滤器
* @param: []
* @return: org.springframework.boot.web.servlet.FilterRegistrationBean
*/
@Bean
public FilterRegistrationBean filterSingleRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new SingleSignOutFilter());
// 设定匹配的路径
registration.addUrlPatterns("/*");
Map initParameters = new HashMap();
initParameters.put("casServerUrlPrefix", CAS_SERVER_URL_PREFIX);
registration.setInitParameters(initParameters);
// 设定加载的顺序
registration.setOrder(1);
return registration;
}
/**
* description:过滤验证器
* * @param: []
* @return: org.springframework.boot.web.servlet.FilterRegistrationBean
*/
@Bean
public FilterRegistrationBean filterValidationRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new Cas30ProxyReceivingTicketValidationFilter());
// 设定匹配的路径
registration.addUrlPatterns("/*");
Map initParameters = new HashMap();
initParameters.put("casServerUrlPrefix", CAS_SERVER_URL_PREFIX);
initParameters.put("serverName", SERVER_NAME);
initParameters.put("useSession", "true");
registration.setInitParameters(initParameters);
// 设定加载的顺序
registration.setOrder(1);
return registration;
}
/**
* description:授权过滤器
* @param: []
* @return: org.springframework.boot.web.servlet.FilterRegistrationBean
*/
@Bean
public FilterRegistrationBean filterAuthenticationRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new AuthenticationFilter());
// 设定匹配的路径
registration.addUrlPatterns("/*");
Map initParameters = new HashMap();
initParameters.put("casServerLoginUrl", CAS_SERVER_URL_LOGIN);
initParameters.put("serverName", SERVER_NAME);
//忽略/logout的路径
initParameters.put("ignorePattern", "/logout/*");
initParameters.put("ignoreUrlPatternType", "com.zhang.springbootcasclient1.auth.SimpleUrlPatternMatcherStrategy");
registration.setInitParameters(initParameters);
// 设定加载的顺序
registration.setOrder(1);
return registration;
}
/**
* wraper过滤器
* @return
*/
@Bean
public FilterRegistrationBean filterWrapperRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new HttpServletRequestWrapperFilter());
// 设定匹配的路径
registration.addUrlPatterns("/*");
// 设定加载的顺序
registration.setOrder(1);
return registration;
}
/**
* 添加监听器
* @return
*/
@Bean
public ServletListenerRegistrationBean singleSignOutListenerRegistration(){
ServletListenerRegistrationBean registrationBean = new ServletListenerRegistrationBean();
registrationBean.setListener(new SingleSignOutHttpSessionListener());
registrationBean.setOrder(1);
return registrationBean;
}
public static void main(String[] args) {
SpringApplication.run(SpringbootCasClient1Application.class, args);
}
}
application.properties
logging.file=logs/config/springboot-cas-client1.log
info.name=springboot-cas-client1
server.port=8001
pom.xml
4.0.0
com.zhang
springboot-cas-client
0.0.1-SNAPSHOT
jar
springboot-cas-client
Demo project for Spring Boot CAS Client
org.springframework.boot
spring-boot-starter-parent
2.0.4.RELEASE
UTF-8
UTF-8
1.8
3.5.0
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-web
org.jasig.cas.client
cas-client-core
${java.cas.client.version}
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
登录测试
按照同样的方法实现客户端系统2。
启动cas服务器端和两个客户端。输入http://springbootcasclient.com:8001/,则跳转到登录界面
输入用户名和密码(casuser/Mellon),则进入客户端系统1的index页面。
输入http://springbootcasclient.com:8002/,直接跳转到客户端系统2的index页面,不需要再重新登录。
单点退出
单点退出,需要下面三个步骤:1、添加过滤器类,过滤掉不需要登录的url;2、添加退出跳转的控制器;3、修改服务端application.properties ,加cas.logout.followServiceRedirects=true,让客户端可以自己制定退出的路径,否则会走默认退出路径。
添加过滤器类
过滤器类需要实现UrlPatternMatcherStrategy接口,然后配置到springboot中,请参考单点登录的创建过滤器类和配置过滤器到springboot。
添加退出控制器
退出的方式有两种,一种是走默认的路径,另一种是走自定义的返回路径。请参考单点登录的用户退出控制器。
修改服务端application.properties
cas.logout.followServiceRedirects=true
将上面的内容添加到applicaiton.properties, 这样就可以允许客户端定制自己的退出路径了。
注意问题
http协议配置:cas 5.3.x默认客户端不支持http协议, 如果不进行配置,则会出现“未认证授权的服务”错误。
要配置兼容http协议,需要在HTTPSandIMAPS-10000001.json文件中添加http。
同时需要在application.properties中添加
cas.serviceRegistry.initFromJson=true