前言
一、CAS是什么?
二、搭建客户端系统
引入CAS
客户端后端搭建
总结
什么是单点登录?单点登录全称Single Sign On(以下简称SSO),是指在多系统应用群中登录一个系统,便可在其他所有系统中得到授权而无需再次登录,包括单点登录与单点注销两部分,如图(不标准,只是方便理解)。
CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。CAS 具有以下特点:
开源的企业级单点登录解决方案。
CAS Server 为需要独立部署的 Web 应用。
CAS Client 支持非常多的客户端(这里指单点登录系统中的各个 Web 应用),包括 Java, .Net, PHP, Perl, Apache, uPortal, Ruby 等。
参考:https://www.bilibili.com/video/BV1xy4y1r7BU?t=666&p=8
注意其中将证书导入jdk中,一定要注意精确到cacerts这个文件下,不然一直报拒绝写入,另外最好用管理员下的命令窗口
1.添加依赖
2.配置客户端
server:port: 1234
3.添加config(filter)
文件
地址全为ip,如果用hosts映射地址,可能会出现问题
package com.casclient1.cas.config;import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.util.HttpServletRequestWrapperFilter;
import org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.filter.CharacterEncodingFilter;import javax.servlet.Filter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;@Configuration
public class FilterConfig implements Serializable, InitializingBean {private static final Logger LOGGER = LoggerFactory.getLogger(FilterConfig.class);public static final String CAS_SIGNOUT_FILTER_NAME = "CAS Single Sign Out Filter";public static final String CAS_AUTH_FILTER_NAME = "CAS Filter";public static final String CAS_IGNOREL_SSL_FILTER_NAME = "CAS Ignore SSL Filter";public static final String CAS_FILTER_NAME = "CAS Validation Filter";public static final String CAS_WRAPPER_NAME = "CAS HttpServletRequest Wrapper Filter";public static final String CAS_ASSERTION_NAME = "CAS Assertion Thread Local Filter";public static final String CHARACTER_ENCODING_NAME = "Character encoding Filter";//CAS服务器退出地址private static String casSigntouServerUrlPrefix = "https://127.0.0.1:8443/cas/logout";//CAS服务器登录地址private static String casServerLoginUrl = "https://127.0.0.1:8443/cas/login";//客户端地址private static String clienthosturl="http://127.0.0.1:1234";//CAS服务器地址private static String casValidationServerUrlPrefix = "https://127.0.0.1:8443/cas";public FilterConfig() {}/*** 单点登出功能,放在其他filter之前* casSigntouServerUrlPrefix为登出前缀:https://123.207.122.156:8081/cas/logout** @return*/@Bean@Order(0)public FilterRegistrationBean getCasSignoutFilterRegistrationBean() {FilterRegistrationBean registration = new FilterRegistrationBean();registration.setFilter(getCasSignoutFilter());registration.addUrlPatterns("/*", "*.html");registration.addInitParameter("casServerUrlPrefix", casSigntouServerUrlPrefix);registration.setName(CAS_SIGNOUT_FILTER_NAME);registration.setEnabled(true);return registration;}@Bean(name = CAS_SIGNOUT_FILTER_NAME)public Filter getCasSignoutFilter() {return new SingleSignOutFilter();}/*** 忽略SSL认证** @return*/@Bean@Order(1)public FilterRegistrationBean getCasSkipSSLValidationFilterRegistrationBean() {FilterRegistrationBean registration = new FilterRegistrationBean();registration.setFilter(getCasSkipSSLValidationFilter());registration.addUrlPatterns("/*", "*.html");registration.setName(CAS_IGNOREL_SSL_FILTER_NAME);registration.setEnabled(true);return registration;}@Bean(name = CAS_IGNOREL_SSL_FILTER_NAME)public Filter getCasSkipSSLValidationFilter() {return new IgnoreSSLValidateFilter();}/*** 负责用户的认证* casServerLoginUrl:https://123.207.122.156:8081/cas/login* casServerName:https://123.207.122.156:8080/tdw/alerts/** @return*/@Bean@Order(2)public FilterRegistrationBean getCasAuthFilterRegistrationBean() {FilterRegistrationBean registration = new FilterRegistrationBean();final Filter casAuthFilter = getCasAuthFilter();registration.setFilter(casAuthFilter);registration.addUrlPatterns("/*", "*.html");registration.addInitParameter("casServerLoginUrl", casServerLoginUrl);registration.addInitParameter("serverName", clienthosturl);registration.setName(CAS_AUTH_FILTER_NAME);registration.setEnabled(true);return registration;}@Bean(name = CAS_AUTH_FILTER_NAME)public Filter getCasAuthFilter() {return new MyAuthenticationFilter();}/*** 对Ticket进行校验* casValidationServerUrlPrefix要用内网ip* casValidationServerUrlPrefix:https://123.207.122.156:8081/cas* casServerName:https://123.207.122.156:8080/tdw/alerts/** @return*/@Bean@Order(3)public FilterRegistrationBean getCasValidationFilterRegistrationBean() {FilterRegistrationBean registration = new FilterRegistrationBean();final Filter casValidationFilter = getCasValidationFilter();registration.setFilter(casValidationFilter);registration.addUrlPatterns("/*", "*.html");registration.addInitParameter("casServerUrlPrefix", casValidationServerUrlPrefix);registration.addInitParameter("serverName", clienthosturl);registration.setName(CAS_FILTER_NAME);registration.setEnabled(true);return registration;}@Bean(name = CAS_FILTER_NAME)public Filter getCasValidationFilter() {return new Cas20ProxyReceivingTicketValidationFilter();}/*** 设置response的默认编码方式:UTF-8。** @return*/@Bean@Order(4)public FilterRegistrationBean getCharacterEncodingFilterRegistrationBean() {FilterRegistrationBean registration = new FilterRegistrationBean();registration.setFilter(getCharacterEncodingFilter());registration.addUrlPatterns("/*", "*.html");registration.setName(CHARACTER_ENCODING_NAME);registration.setEnabled(true);return registration;}@Bean(name = CHARACTER_ENCODING_NAME)public Filter getCharacterEncodingFilter() {CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();characterEncodingFilter.setEncoding("UTF-8");return characterEncodingFilter;}@Beanpublic FilterRegistrationBean casHttpServletRequestWrapperFilter(){FilterRegistrationBean authenticationFilter = new FilterRegistrationBean();authenticationFilter.setFilter(new HttpServletRequestWrapperFilter());authenticationFilter.setOrder(6);List
}
4.filter类中的MyAuthenticationFilter
是重写cas jar包中的AuthenticationFilter
,原因是CAS源码无法认证直接重定向,而ajax请求又不能直接重定向,导致前端302,而302vue response拦截器是拦截不到的。所以就想到不让cas给我重定向,给我返回状态码,告诉前端认证失败,让前端直接跳转cas服务器登录地址。
修改cas源码过滤器,复制源码AuthenticationFilter
这个过滤器,重写他,其实这里只改了重定向的代码其他都一样。上MyAuthenticationFilter
代码
package com.casclient1.cas.config;import org.jasig.cas.client.authentication.*;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.util.ReflectUtils;
import org.jasig.cas.client.validation.Assertion;import javax.servlet.FilterConfig;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;public class MyAuthenticationFilter extends AbstractCasFilter {private String casServerLoginUrl;private boolean renew = false;private boolean gateway = false;private GatewayResolver gatewayStorage = new DefaultGatewayResolverImpl();private AuthenticationRedirectStrategy authenticationRedirectStrategy = new DefaultAuthenticationRedirectStrategy();private UrlPatternMatcherStrategy ignoreUrlPatternMatcherStrategyClass = null;private static final Map
}
测试Controller
package com.casclient1.cas.controller;import com.casclient1.cas.domain.UserDomain;
import com.casclient1.cas.tools.Result;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Console;
import java.io.IOException;@Controller
public class TestController {/*** 测试* @return*/@GetMapping("/test")@ResponseBodypublic Result
3.前端
5.效果
未登录:
点击客户端1超链接
登录成功
点击客户端2超链接,直接进入,无需登录
退出
网上有很多CAS单点登录的demo,但是对于前后端分离讲的比较详细的很少,前后端分离,必定会出现跨域,导致CAS登录无法重定向等等原因,结合和网上一些想法和部门代码后,大致做了一个比较完善,但很基础的单点登录系统,当然单点登录不光有CAS,还有JWT(1.所有服务靠约定来生成token,2.要么集中生成集中判断,所有服务都能生成都认这个,要么一个服务管控全局),OAuth2等等。
来源:blog.csdn.net/weixin_43483911/article/details/117811270