因为现有系统外部接入需要,需要支持三方单点登录。由于系统本身已经是微服务架构,由多个业务独立的子系统组成,所以有自己的用户认证微服务(不是cas,我们基础设施已经够多了,现在能不增加就不增加)。但是因为客户和其他接入(公有云网络)原因,无法通过token+redis实现,所以还需要支持外部的cas。

现有认证系统采用shiro实现,业务子系统采用shiro+token假登录实现。现在要支持通过配置设置系统自身的认证子系统是否启用三方cas登录。这样无论是使用自己的认证实现、还是三方CAS,整体流程就完全一样。

CAS服务器搭建

从cas 4开始,官方就已经不再提供release war,转而需要自行下载源码打包,网上很多,这里不再阐述(下载依赖有点慢)。4.x以及之前的war可以从https://mvnrepository.com/artifact/org.jasig.cas/cas-server-webapp下载。下载后,解压到tomcat webapp目录:

启动:

修改下列配置:

去除https认证:

在tomcat\webapps\cas\WEB-INF\deployerConfigContext.xml文件
的p:httpClient-ref="httpClient"后面添加p:requireSecure="false"
把tomcat\webapps\cas\WEB-INF\spring-configuration的
ticketGrantingTicketCookieGenerator.xml文件里面把p:cookieSecure="true"改为false;
p:cookieMaxAge="-1"改为3600(-1是不保存cookie,3600秒是一个小时,保存登录信息)
把tomcat\webapps\cas\WEB-INF\spring-configuration的
warnCookieGenerator.xml的p:cookieSecure="true"改为false
p:cookieMaxAge="-1"改为3600

配置单点登出:

  将tomcat\webapps\cas\WEB-INF\cas-servlet.xml中${cas.logout.followServiceRedirects:false}括号里的值改为true

可以配置简单测试认证(去掉<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />注释)或基于数据源认证(可以参考https://www.cnblogs.com/wlwl/p/10056067.html)。

spring boot cas客户端集成

库依赖:

        <dependency>
<groupId>net.unicon.cas</groupId>
<artifactId>cas-client-autoconfig-support</artifactId>
<version>1.5.0-GA</version>
</dependency>
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.2.1</version>
<exclusions>
<exclusion>
<artifactId>servlet-api</artifactId>
<groupId>javax.servlet</groupId>
</exclusion>
</exclusions>
</dependency>

application.properties中加上下列配置:

cas.server-url-prefix=http://localhost:8080/cas
cas.server-login-url=http://localhost:8080/cas/login
cas.client-host-url=http://localhost:18080/
cas.use-session=true
cas.validation-type=cas
casClientLogoutUrl=http://localhost:8080/cas/logout?service=http://localhost:18080/tabase/logout.html
import net.unicon.cas.client.configuration.EnableCasClient;

@EnableCasClient //启用cas client
@CloudApplication
public class ConsumerStarter {
public static void main(String[] args) {
CloudBootstrap.run(ConsumerStarter.class, args);
}
} package com.hs; import java.util.HashMap;
import java.util.Map; import org.jasig.cas.client.authentication.AuthenticationFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration
public class CASAutoConfig {
@Value("${cas.server-url-prefix}")
private String serverUrlPrefix;
@Value("${cas.server-login-url}")
private String serverLoginUrl;
@Value("${cas.client-host-url}")
private String clientHostUrl; /**
* 授权过滤器
* @return
*/
@Bean
public FilterRegistrationBean filterAuthenticationRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new AuthenticationFilter());
// 设定匹配的路径
registration.addUrlPatterns("/*");
Map<String,String> initParameters = new HashMap<String, String>();
initParameters.put("casServerLoginUrl", serverUrlPrefix);
initParameters.put("serverName", clientHostUrl);
//忽略的url,"|"分隔多个url
initParameters.put("ignorePattern", "/logout/success|/index");
registration.setInitParameters(initParameters);
// 设定加载的顺序
registration.setOrder(1);
return registration;
}
}

shiro模拟登录(不修改现有shiro认证架构)

cas登录成功后,会给应用返回ticket,其中包含了用户名。此时应用主页会被shiro过滤器UserFilter拦截,在其中可以判断HttpServletRequest上是否有ticket的用户名,有、且为有效用户名,就可以用该用户名模拟登录了。这样整个shiro认证流程几乎没有变化,也不需要修改FormAuthenticationFilter。

cas在2.x和3.x版本获取用户名不一样,这一点需要注意。

2.x版本client获取CAS传递过来的用户名的方法:

// 以下三者都可以
session.getAttribute(CASFilter.CAS_FILTER_USER);
session.getAttribute("edu.yale.its.tp.cas.client.filter.user"); CASFilterRequestWrapper reqWrapper=new CASFilterRequestWrapper(request);
reqWrapper.getRemoteUser());

3.x版本client获取CAS传递过来的用户名的方法:

HttpServletRequest request = ServletActionContext.getRequest();
AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal();
String username = principal.getName();
Long orgnId = Long.parseLong(principal.getAttributes().get("orgnId").toString());

拿到后,就可以模拟登陆了。

        boolean isAllowed = super.isAccessAllowed(request, response, mappedValue);
//
if (isAllowed) { } else if (Boolean.valueOf(BaseConfig.getConfig("ta.casEnable","false"))) {
AttributePrincipal principal = (AttributePrincipal)((HttpServletRequest) request).getUserPrincipal();
String username = principal.getName();
Subject subject = getSubject(request, response);
AuthenticationToken token = new UsernamePasswordToken();
((UsernamePasswordToken) token).setUsername(username);
((UsernamePasswordToken) token).setPassword(new char[] {'1'});
subject.login(token);
isAllowed = super.isAccessAllowed(request, response, mappedValue);
}

shiro登出

在shiro的logoutFilter中调用session.invalidate()即可。然后返回casClientLogoutUrl配置的地址退出cas即可。

        /**
* CAS添加开始
*/
if (StringUtils.isNotBlank(BaseConfig.getConfig("casClientLogoutUrl"))) {
((HttpServletRequest)request).getSession().invalidate();
redirectUrl = BaseConfig.getConfig("casClientLogoutUrl");
}
// CAS添加结束
return redirectUrl;

此致,就完整的实现了cas+shiro模拟登录。

CAS ticket过期策略,参考:https://www.cnblogs.com/gao241/p/3367869.html

CAS流程介绍,参考:https://www.cnblogs.com/xiatian0721/p/8136305.html

CAS官方架构参考:https://apereo.github.io/cas/5.3.x/planning/Architecture.html

最新文章

  1. 1、开篇:公司管理经验谈 - CEO之公司管理经验谈
  2. win7下IIS的安装和配置 图文教程
  3. tnt_esri.dat Arcgis8.1安装license
  4. spring(3) JDBC
  5. scrapy 登录
  6. Hibernate配置属性
  7. hdu 4740
  8. 【angular】angular实现简单的tab切换
  9. 201521123026 《Java程序设计》第三周学习总结
  10. Codeforces Round #427 (Div. 2) D - Palindromic characteristics
  11. ccf--20160403---路径解析
  12. 用addOnGlobalLayoutListener获取View的宽高
  13. CentOS7永久挂载硬盘
  14. 在sublime text2上安装xdebug
  15. POST—常见的4种提交方式
  16. 【Udacity】机器学习性能评估指标
  17. 实现RTSP网站微信直播方案EasyNVR(linux版)部署问题之:ERR_CONTENT_LENGTH_MISMATCH
  18. MySQL 当记录不存在时插入,当记录存在时更新
  19. 计算机组成原理--64位CPU装载32位操作系统,它的寻址能力还是4GB吗?
  20. nopCommerce 3.9 接口笔记

热门文章

  1. Linux安装和配置MySQL5.7【修改密码、修改字符集等配置】(5.7.18+版本也可参考,我是5.7.22)
  2. 尚学堂JAVA基础学习笔记
  3. Linux服务-bind
  4. 基于JFinal中搭建wopi协议支撑办法
  5. 【Miscalculation UVALive - 6833 】【模拟】
  6. 基于Docker容器使用NVIDIA-GPU训练神经网络
  7. EF 多数据库切换配置(MSSQL/MySql)
  8. django-用户浏览记录添加及商品详情页
  9. django-模板变量forloop
  10. 基于麦克风阵列的声源定位算法之GCC-PHAT