javaweb项目接入CAS单点认证(含自身系统的三员过滤)
创始人
2024-05-02 14:49:01
0

一、搭建cas server
1.下载war包
在这里插入图片描述
2.打开cmd窗口执行以下命令,命令如下(指定ip):

keytool -genkey -v -alias casbm -keyalg RSA -keystore D:\cas\keystore\casbm.keystore -ext SAN=IP:192.168.2.166 

3.我们生成秘钥库后需要从秘钥库中导出证书,打开cmd窗口,命令如下:

keytool -export -trustcacerts -alias casbm -file D:/cas/keystore/casbm.cer -keystore D:/cas/keystore/casbm.keystore

4.我们从秘钥库导出证书后需要将证书导入到JDK证书库中,打开cmd窗口,命令如下,其中最后的路径为你本地jdk的路径,要确保该路径正确(此处密码不是自己设置的,是默认密码:changeit):
keytool -import -trustcacerts -alias casbm -file D:/cas/keystore/casbm.cer -keystore “D:/Configure/java/java8/jre/lib/security/cacerts”
5.由于cas需要https协议访问,所以我们要配置tomcat也支持https协议,我们找到我们的tomcat的server.xml文件,加入如下配置:


6.将之前下载的cas包放入tomcat中启动,首先将war包放入tomcat的webapps下,改名为cas,启动tomcat
7.启动完成后我们访问登录页面验证是否启动成功,访问地址如下,用户名为:casuser 密码为:Mellon:
https://localhost:8443/cas
8.用户名密码是在application.properties配置文件中指定的(需要删除原cas.war,避免覆盖)

##
# CAS Authentication Credentials
#
cas.authn.accept.users=dagly::most123456789
#cas.authn.jdbc.query[0].url=jdbc:kingbase8://192.168.2.166:54321/WANGLIAN#cas.authn.jdbc.query[0].user=WANGLIAN#cas.authn.jdbc.query[0].password=manager123#cas.authn.jdbc.query[0].sql=select * from hdrole where login_name = ?#cas.authn.jdbc.query[0].fieldPassword=password#cas.authn.jdbc.query[0].driverClass=com.kingbase8.Driver#cas.authn.jdbc.query[0].passwordEncoder.type=DEFAULT#cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=GBK
#MD5加密策略#cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD5#是否开启json识别功能,默认为false
cas.serviceRegistry.initFromJson=true
#忽略https安全协议,使用 HTTP 协议
cas.tgc.secure=false
cas.logout.followServiceRedirects=true

9.使用数据库连接时加入jar:

cas-server-support-jdbc-5.3.1.jarcas-server-support-jdbc-drivers-5.3.1.jarcas-server-support-jdbc-authentication-5.3.1.jarconnector-java-5.1.34_1.jar

二、接入CAS 的client
1.修改tomcat的server.xml引入证书:,项目中引入cas-client-core-3.6.4.jar


2.在web.xml中加入配置(删掉注释,此处为了解释):

//单点登出的listener
org.jasig.cas.client.session.SingleSignOutHttpSessionListener//单点登出过滤器CAS Single Sign Out Filterorg.jasig.cas.client.session.SingleSignOutFilterCAS Single Sign Out Filter/*//自定义的顶层filer,用于处理请求FetchCasTicketFiltercom.hidy.auth.servlet.FetchCasTicketFilterFetchCasTicketFilter/*//认证过滤器,此处重写,用官方的无法配置不过滤的路径CASFiltercom.hidy.auth.servlet.AuthenticationFiltercasServerLoginUrlhttps://192.168.2.166:8443/cas/login//CAS server登录页serverNamehttp://192.168.2.166:8080///项目地址ignorePattern/defaultpsy.*|/theme/*|/LoginServlet|/images/*|/TransInterface//CASFilter/*CAS Validation Filter//认证拦截器org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFiltertargetBeanNameloginSinglePointScoreBpcasServerUrlPrefixhttps://192.168.2.166:8443/casserverNamehttp://192.168.2.166:8080/CAS Validation Filter/*//处理request,能够用request.getRemoteUser()获取当前登录人CAS HttpServletRequest Wrapper Filterorg.jasig.cas.client.util.HttpServletRequestWrapperFilterCAS HttpServletRequest Wrapper Filter/*//单点的登录servlet(即对原来的登录servlet复制,逻辑进行修改,原来的用于三员登录)LoginServletCascom.hidy.auth.servlet.LoginServletCasLoginServletCas/LoginServletCas

3.FetchCasTicketFilter代码,顶级过滤器

package com.hidy.auth.servlet;import java.io.IOException;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.jasig.cas.client.util.CommonUtils;import com.hidy.hdoa6.util.StaticData;import org.jasig.cas.client.util.CommonUtils;public class FetchCasTicketFilter implements Filter {@Overridepublic void destroy() {// TODO Auto-generated method stub}@Overridepublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response=(HttpServletResponse) res;String path = request.getServletPath();Object id = request.getSession().getAttribute("UserID");String ticket = request.getParameter("ticket");String requestUri=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";//对一些路径不拦截if(id == null && ticket==null && !(path.endsWith("defaultp.jsp") || path.endsWith(".js") || path.endsWith(".css") || path.endsWith("/LoginServlet")|| path.endsWith("/LoginServletCas")|| path.endsWith("/defaultpsy.jsp")|| path.endsWith(".png")||path.endsWith("/TransInterface"))) {String result = "";response.getWriter().print(result);response.getWriter().close();}else {//获取cas的ticket,看cas server配置的规则,如果是认证完即失效,则此处可以不写String queryString = request.getQueryString();if(queryString != null && queryString.contains("ticket")){Cookie cookie=new Cookie("ticket",queryString.substring(queryString.indexOf("=") + 1) );cookie.setMaxAge(Integer.MAX_VALUE);//将Cookie加到response中response.addCookie(cookie);}chain.doFilter(req, res);}}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}}

4.AuthenticationFilter代码(不一定一致,当前用的cas client core3.6.4,其他版本反编译后修改逻辑,主要是对不拦截路径的放行)

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.jasig.cas.client.Protocol;
import org.jasig.cas.client.authentication.AuthenticationRedirectStrategy;
import org.jasig.cas.client.authentication.ContainsPatternUrlPatternMatcherStrategy;
import org.jasig.cas.client.authentication.DefaultAuthenticationRedirectStrategy;
import org.jasig.cas.client.authentication.DefaultGatewayResolverImpl;
import org.jasig.cas.client.authentication.EntireRegionRegexUrlPatternMatcherStrategy;
import org.jasig.cas.client.authentication.ExactUrlPatternMatcherStrategy;
import org.jasig.cas.client.authentication.GatewayResolver;
import org.jasig.cas.client.authentication.RegexUrlPatternMatcherStrategy;
import org.jasig.cas.client.authentication.UrlPatternMatcherStrategy;
import org.jasig.cas.client.configuration.ConfigurationKey;
import org.jasig.cas.client.configuration.ConfigurationKeys;
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;
public class AuthenticationFilter extends AbstractCasFilter {private String casServerLoginUrl;private boolean renew;private boolean gateway;private String method;private GatewayResolver gatewayStorage;private AuthenticationRedirectStrategy authenticationRedirectStrategy;private UrlPatternMatcherStrategy ignoreUrlPatternMatcherStrategyClass;private static final Map> PATTERN_MATCHER_TYPES = new HashMap();private String excludePaths;  public AuthenticationFilter() {this(Protocol.CAS2);}protected AuthenticationFilter(Protocol protocol) {super(protocol);this.renew = false;this.gateway = false;this.gatewayStorage = new DefaultGatewayResolverImpl();this.authenticationRedirectStrategy = new DefaultAuthenticationRedirectStrategy();this.ignoreUrlPatternMatcherStrategyClass = null;}protected void initInternal(FilterConfig filterConfig) throws ServletException {if (!this.isIgnoreInitConfiguration()) {super.initInternal(filterConfig);String loginUrl = this.getString(ConfigurationKeys.CAS_SERVER_LOGIN_URL);if (loginUrl != null) {this.setCasServerLoginUrl(loginUrl);} else {this.setCasServerUrlPrefix(this.getString(ConfigurationKeys.CAS_SERVER_URL_PREFIX));}this.setRenew(this.getBoolean(ConfigurationKeys.RENEW));this.setGateway(this.getBoolean(ConfigurationKeys.GATEWAY));this.setMethod(this.getString(ConfigurationKeys.METHOD));String ignorePattern = this.getString(ConfigurationKeys.IGNORE_PATTERN);String ignoreUrlPatternType = this.getString(ConfigurationKeys.IGNORE_URL_PATTERN_TYPE);Class gatewayStorageClass;if (ignorePattern != null) {gatewayStorageClass = (Class)PATTERN_MATCHER_TYPES.get(ignoreUrlPatternType);if (gatewayStorageClass != null) {this.ignoreUrlPatternMatcherStrategyClass = (UrlPatternMatcherStrategy)ReflectUtils.newInstance(gatewayStorageClass.getName(), new Object[0]);} else {try {this.logger.trace("Assuming {} is a qualified class name...", ignoreUrlPatternType);this.ignoreUrlPatternMatcherStrategyClass = (UrlPatternMatcherStrategy)ReflectUtils.newInstance(ignoreUrlPatternType, new Object[0]);} catch (IllegalArgumentException var7) {this.logger.error("Could not instantiate class [{}]", ignoreUrlPatternType, var7);}}if (this.ignoreUrlPatternMatcherStrategyClass != null) {this.ignoreUrlPatternMatcherStrategyClass.setPattern(ignorePattern);}}gatewayStorageClass = this.getClass(ConfigurationKeys.GATEWAY_STORAGE_CLASS);if (gatewayStorageClass != null) {this.setGatewayStorage((GatewayResolver)ReflectUtils.newInstance(gatewayStorageClass, new Object[0]));}Class authenticationRedirectStrategyClass = this.getClass(ConfigurationKeys.AUTHENTICATION_REDIRECT_STRATEGY_CLASS);if (authenticationRedirectStrategyClass != null) {this.authenticationRedirectStrategy = (AuthenticationRedirectStrategy)ReflectUtils.newInstance(authenticationRedirectStrategyClass, new Object[0]);}excludePaths = this.getString(new ConfigurationKey("ignorePattern", (Object)null));excludePaths = excludePaths.trim();}}public void init() {super.init();String message = String.format("one of %s and %s must not be null.", ConfigurationKeys.CAS_SERVER_LOGIN_URL.getName(), ConfigurationKeys.CAS_SERVER_URL_PREFIX.getName());CommonUtils.assertNotNull(this.casServerLoginUrl, message);}public final void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest)servletRequest;HttpServletResponse response = (HttpServletResponse)servletResponse;
//三员用户直接放行        if(null!=request.getSession().getAttribute("isXtgly")||null!=request.getSession().getAttribute("isAqbmy")||null!=request.getSession().getAttribute("isAqsjy")) {filterChain.doFilter(request, response);return;}if (this.isRequestUrlExcluded(request)) {this.logger.debug("Request is ignored.");filterChain.doFilter(request, response);return;} else {HttpSession session = request.getSession(false);Assertion assertion = session != null ? (Assertion)session.getAttribute("_const_cas_assertion_") : null;if (assertion != null) {filterChain.doFilter(request, response);} else {String serviceUrl = this.constructServiceUrl(request, response);String ticket = this.retrieveTicketFromRequest(request);boolean wasGatewayed = this.gateway && this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);if (!CommonUtils.isNotBlank(ticket) && !wasGatewayed) {this.logger.debug("no ticket and no assertion found");String modifiedServiceUrl;if (this.gateway) {this.logger.debug("setting gateway attribute in session");modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);} else {modifiedServiceUrl = serviceUrl;}this.logger.debug("Constructed service url: {}", modifiedServiceUrl);String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, this.getProtocol().getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway, this.method);this.logger.debug("redirecting to \"{}\"", urlToRedirectTo);this.authenticationRedirectStrategy.redirect(request, response, urlToRedirectTo);} else {filterChain.doFilter(request, response);}}}}public final void setRenew(boolean renew) {this.renew = renew;}public final void setGateway(boolean gateway) {this.gateway = gateway;}public void setMethod(String method) {this.method = method;}public final void setCasServerUrlPrefix(String casServerUrlPrefix) {this.setCasServerLoginUrl(CommonUtils.addTrailingSlash(casServerUrlPrefix) + "login");}public final void setCasServerLoginUrl(String casServerLoginUrl) {this.casServerLoginUrl = casServerLoginUrl;}public final void setGatewayStorage(GatewayResolver gatewayStorage) {this.gatewayStorage = gatewayStorage;}
//自行修改代码private boolean isRequestUrlExcluded(HttpServletRequest request) {if (this.ignoreUrlPatternMatcherStrategyClass == null) {return false;} else {StringBuffer urlBuffer = request.getRequestURL();if (request.getQueryString() != null) {urlBuffer.append("?").append(request.getQueryString());}String requestUri = urlBuffer.toString();return this.ignoreUrlPatternMatcherStrategyClass.matches(requestUri);}}public final void setIgnoreUrlPatternMatcherStrategyClass(UrlPatternMatcherStrategy ignoreUrlPatternMatcherStrategyClass) {this.ignoreUrlPatternMatcherStrategyClass = ignoreUrlPatternMatcherStrategyClass;}static {PATTERN_MATCHER_TYPES.put("CONTAINS", ContainsPatternUrlPatternMatcherStrategy.class);PATTERN_MATCHER_TYPES.put("REGEX", RegexUrlPatternMatcherStrategy.class);PATTERN_MATCHER_TYPES.put("FULL_REGEX", EntireRegionRegexUrlPatternMatcherStrategy.class);PATTERN_MATCHER_TYPES.put("EXACT", ExactUrlPatternMatcherStrategy.class);}
}

5.登录页验证是否已经cas登录

	String user=request.getRemoteUser();String casloginflag="false";if(!"".equals(user)&&null!=user){//已经在cas登录casloginflag="true";}为true是直接跳转到LoginServletCas

6.三员
复制一个登录页,登录servlet,不验证cas,只验证session中三员是否登录,此页面需要在web.xml中修改,放行此页面和相关servlet(包括上面AuthenticationFilter的逻辑处理)
参考资料:
CAS实现单点登录
自定义cas客户端核心过滤器AuthenticationFilter
其他

相关内容

热门资讯

开源电脑安卓系统排行,探索自由... 亲爱的电脑爱好者们,你是否曾想过,在电脑的世界里,也能体验到安卓系统的便捷与乐趣?没错,这就是今天我...
如何清空相册安卓系统,轻松恢复... 手机里的相册是不是越来越满,看着那些堆积如山的照片,是不是有点头疼呢?别急,今天就来教你怎么在安卓系...
安卓系统要停止更新,拥抱新变革 你知道吗?最近有个大消息在安卓圈里炸开了锅!安卓系统,这个陪伴我们多年的老朋友,竟然要停止更新了!这...
安卓系统怎样强行关机,安卓系统... 手机突然卡壳了,是不是又想强行关机了?别急,今天就来教你安卓系统怎样强行关机,让你轻松应对各种突发状...
安卓系统如何删除桌面,轻松删除... 手机桌面乱糟糟的,是不是感觉像你的房间一样,东西堆得有点多?别急,今天就来教你怎么给安卓系统的桌面来...
安卓系统怎么发英语,Andro... 你有没有想过,在安卓系统上发送英语信息竟然也能变得如此简单有趣?没错,就是那种轻松自如,仿佛英语是你...
最早期的安卓系统,揭秘最早期安... 亲爱的读者,你是否曾好奇过,那个陪伴我们手机成长的安卓系统,它的起源究竟是怎样的呢?今天,就让我们一...
安卓双系统添加应用,轻松实现多... 你有没有想过,你的安卓手机里可以同时运行两个系统呢?听起来是不是很酷?想象一边是熟悉的安卓系统,一边...
pipo安卓进系统慢,探究pi... 最近是不是发现你的Pipo安卓系统更新或者运行起来特别慢?别急,今天就来给你好好分析分析这个问题,让...
怎样使用安卓手机系统,安卓手机... 你有没有发现,安卓手机已经成为我们生活中不可或缺的一部分呢?从早晨闹钟响起,到晚上睡前刷剧,安卓手机...
双系统安卓安装caj,轻松实现... 你有没有想过,你的安卓手机里装上双系统,是不是就能同时享受安卓和Windows系统的乐趣呢?没错,这...
安卓使用ios系统教程,安卓用... 你是不是也和我一样,对安卓手机上的iOS系统充满了好奇?想要体验一下苹果的优雅和流畅?别急,今天我就...
安卓系统gps快速定位,畅享便... 你有没有遇到过这样的情况:手机里装了各种地图导航软件,但每次出门前都要等上好几分钟才能定位成功,急得...
安卓手机系统更新原理,原理与流... 你有没有发现,你的安卓手机最近是不是总在提醒你更新系统呢?别急,别急,让我来给你揭秘一下安卓手机系统...
安卓系统通知管理,全面解析与优... 你有没有发现,手机里的通知就像是一群调皮的小精灵,时不时地跳出来和你互动?没错,说的就是安卓系统的通...
安卓系统手机哪买,揭秘哪里购买... 你有没有想过,拥有一部安卓系统手机是多么酷的事情呢?想象你可以自由安装各种应用,不受限制地探索各种功...
安卓系统 ipv4,基于安卓系... 你知道吗?在智能手机的世界里,有一个系统可是无人不知、无人不晓,那就是安卓系统。而在这个庞大的安卓家...
目前安卓是什么系统,探索安卓系... 亲爱的读者,你是否曾好奇过,如今安卓系统究竟是什么模样?在这个科技飞速发展的时代,操作系统如同人体的...
安卓6.0系统比5.0,从5.... 你有没有发现,自从手机更新了安卓6.0系统,感觉整个人都清爽了不少呢?没错,今天咱们就来聊聊这个话题...
安卓2.36系统升级,功能革新... 你知道吗?最近安卓系统又来了一次大变身,那就是安卓2.36系统升级!这可不是一个小打小闹的更新,而是...