cas_client之AuthenticationFilter源码分析

packageorg.jasig.cas.client.authentication;

import java.io.IOException;

import java.io.PrintStream;

import java.util.Date;

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;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

import org.jasig.cas.client.util.AbstractCasFilter;

importorg.jasig.cas.client.util.CommonUtils;

importorg.jasig.cas.client.util.ReflectUtils;

importorg.jasig.cas.client.validation.Assertion;

import org.slf4j.Logger;

public class AuthenticationFilter

extends AbstractCasFilter

{

//sso中心认证服务的登录地址。

private String casServerLoginUrl;

private boolean renew = false;

private boolean gateway = false;

//网关存储解析器。

private GatewayResolver gatewayStorage = newDefaultGatewayResolverImpl();

//认证重定向策略,默认是直接重定向地址。

private AuthenticationRedirectStrategy authenticationRedirectStrategy =new DefaultAuthenticationRedirectStrategy();

//可以被忽略的url模式匹配策略。

private UrlPatternMatcherStrategy ignoreUrlPatternMatcherStrategyClass =null;

private static final Map<String, Class<? extendsUrlPatternMatcherStrategy>> PATTERN_MATCHER_TYPES = new HashMap();

//默认有3种模式匹配策略:包含、正则、相等。

static

{

PATTERN_MATCHER_TYPES.put("CONTAINS",ContainsPatternUrlPatternMatcherStrategy.class);

PATTERN_MATCHER_TYPES.put("REGEX",RegexUrlPatternMatcherStrategy.class);

PATTERN_MATCHER_TYPES.put("EXACT",ExactUrlPatternMatcherStrategy.class);

}

protected void initInternal(FilterConfig filterConfig)

throws ServletException

{

if (!isIgnoreInitConfiguration())

{

super.initInternal(filterConfig);

setCasServerLoginUrl(getPropertyFromInitParams(filterConfig,"casServerLoginUrl", null));

this.logger.trace("Loaded CasServerLoginUrl parameter: {}",this.casServerLoginUrl);

setRenew(parseBoolean(getPropertyFromInitParams(filterConfig,"renew", "false")));

this.logger.trace("Loaded renew parameter: {}",Boolean.valueOf(this.renew));

setGateway(parseBoolean(getPropertyFromInitParams(filterConfig,"gateway", "false")));

this.logger.trace("Loaded gateway parameter: {}",Boolean.valueOf(this.gateway));

//忽略模式:可以自定义、根据实际情况配置,默认是正则表达式。

String ignorePattern = getPropertyFromInitParams(filterConfig,"ignorePattern", null);

this.logger.trace("Loaded ignorePattern parameter: {}",ignorePattern);

//默认是正则模式,可以自定义实现UrlPatternMatcherStrategy接口。

String ignoreUrlPatternType = getPropertyFromInitParams(filterConfig,"ignoreUrlPatternType", "REGEX");

this.logger.trace("Loaded ignoreUrlPatternType parameter: {}",ignoreUrlPatternType);

if (ignorePattern != null)

{

Class<? extends UrlPatternMatcherStrategy> ignoreUrlMatcherClass =(Class)PATTERN_MATCHER_TYPES.get(ignoreUrlPatternType);

if (ignoreUrlMatcherClass != null) {

this.ignoreUrlPatternMatcherStrategyClass = ((UrlPatternMatcherStrategy)ReflectUtils.newInstance(ignoreUrlMatcherClass.getName(),new Object[0]));

} else {

try

{

this.logger.trace("Assuming {} is a qualified class name...",ignoreUrlPatternType);

this.ignoreUrlPatternMatcherStrategyClass =((UrlPatternMatcherStrategy)ReflectUtils.newInstance(ignoreUrlPatternType, newObject[0]));

}

catch (IllegalArgumentException e)

{

this.logger.error("Could not instantiate class [{}]",ignoreUrlPatternType, e);

}

}

if (this.ignoreUrlPatternMatcherStrategyClass != null) {

this.ignoreUrlPatternMatcherStrategyClass.setPattern(ignorePattern);

}

}

String gatewayStorageClass = getPropertyFromInitParams(filterConfig,"gatewayStorageClass", null);

if (gatewayStorageClass != null) {

this.gatewayStorage =((GatewayResolver)ReflectUtils.newInstance(gatewayStorageClass, newObject[0]));

}

String authenticationRedirectStrategyClass =getPropertyFromInitParams(filterConfig,"authenticationRedirectStrategyClass", null);

if (authenticationRedirectStrategyClass != null) {

this.authenticationRedirectStrategy =((AuthenticationRedirectStrategy)ReflectUtils.newInstance(authenticationRedirectStrategyClass,new Object[0]));

}

}

}

public void init()

{

super.init();

CommonUtils.assertNotNull(this.casServerLoginUrl,"casServerLoginUrl cannot be null.");

}

public final void doFilter(ServletRequest servletRequest,ServletResponse servletResponse, FilterChain filterChain)

throws IOException, ServletException

{

HttpServletRequest request = (HttpServletRequest)servletRequest;

HttpServletResponse response = (HttpServletResponse)servletResponse;

//判断当前请求url是否可以被忽略模式匹配认证通过。

if (isRequestUrlExcluded(request))

{

this.logger.debug("Request is ignored.");

filterChain.doFilter(request, response);

return;

}

//获取sso认证中心存储的session属性_const_cas_assertion_。

HttpSession session = request.getSession(false);

Assertion assertion = session != null ?(Assertion)session.getAttribute("_const_cas_assertion_") : null;

if (assertion != null)

{

filterChain.doFilter(request, response);

return;

}

//从request中构建需要认证的服务url。

String serviceUrl = constructServiceUrl(request, response);

//从request中获取票据ticket。

String ticket = retrieveTicketFromRequest(request);

//如果设置网关,则从session当中获取属性_const_cas_gateway,并从session中去掉此属性。

boolean wasGatewayed = (this.gateway) &&(this.gatewayStorage.hasGatewayedAlready(request, serviceUrl));

//如果存在认证票据ticket或者网关设置,则直接认证通过。

if ((CommonUtils.isNotBlank(ticket)) || (wasGatewayed))

{

filterChain.doFilter(request, response);

return;

}

this.logger.debug("no ticket and no assertion found");

String modifiedServiceUrl;

if (this.gateway)

{

this.logger.debug("setting gateway attribute in session");

//在session中设置网关属性_const_cas_gateway=yes

modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request,serviceUrl);

}

else

{

modifiedServiceUrl = serviceUrl;

}

this.logger.debug("Constructed service url: {}",modifiedServiceUrl);

//直接重定向sso认证中心url,进行登录认证。

String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl,getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);

this.logger.debug("redirecting to \"{}\"",urlToRedirectTo);

this.authenticationRedirectStrategy.redirect(request, response,urlToRedirectTo);

}

public final void setRenew(boolean renew)

{

this.renew = renew;

}

public final void setGateway(boolean gateway)

{

this.gateway = gateway;

}

public final void setCasServerLoginUrl(String casServerLoginUrl)

{

this.casServerLoginUrl = casServerLoginUrl;

}

public final void setGatewayStorage(GatewayResolver gatewayStorage)

{

this.gatewayStorage = gatewayStorage;

}

//根据可以忽略的URL地址匹配策略,来判断当前请求url是否可以认证:因此在配置此过滤器的时候,如果存在不需要认证的url,那么就可以根据url的形式配置ignorePattern参数和ignoreUrlPatternType参数。

private boolean isRequestUrlExcluded(HttpServletRequest request)

{

if (this.ignoreUrlPatternMatcherStrategyClass == null) {

return false;

}

StringBuffer urlBuffer = request.getRequestURL();

if (request.getQueryString() != null) {

urlBuffer.append("?").append(request.getQueryString());

}

String requestUri = urlBuffer.toString();

return this.ignoreUrlPatternMatcherStrategyClass.matches(requestUri);

}

}

时间: 2024-12-20 03:04:40

cas_client之AuthenticationFilter源码分析的相关文章

TeamTalk源码分析之login_server

login_server是TeamTalk的登录服务器,负责分配一个负载较小的MsgServer给客户端使用,按照新版TeamTalk完整部署教程来配置的话,login_server的服务端口就是8080,客户端登录服务器地址配置如下(这里是win版本客户端): 1.login_server启动流程 login_server的启动是从login_server.cpp中的main函数开始的,login_server.cpp所在工程路径为server\src\login_server.下表是logi

Android触摸屏事件派发机制详解与源码分析二(ViewGroup篇)

1 背景 还记得前一篇<Android触摸屏事件派发机制详解与源码分析一(View篇)>中关于透过源码继续进阶实例验证模块中存在的点击Button却触发了LinearLayout的事件疑惑吗?当时说了,在那一篇咱们只讨论View的触摸事件派发机制,这个疑惑留在了这一篇解释,也就是ViewGroup的事件派发机制. PS:阅读本篇前建议先查看前一篇<Android触摸屏事件派发机制详解与源码分析一(View篇)>,这一篇承接上一篇. 关于View与ViewGroup的区别在前一篇的A

HashMap与TreeMap源码分析

1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Java这么久,也写过一些小项目,也使用过TreeMap无数次,但到现在才明白它的实现原理).因此本着"不要重复造轮子"的思想,就用这篇博客来记录分析TreeMap源码的过程,也顺便瞅一瞅HashMap. 2. 继承结构 (1) 继承结构 下面是HashMap与TreeMap的继承结构: pu

Linux内核源码分析--内核启动之(5)Image内核启动(rest_init函数)(Linux-3.0 ARMv7)【转】

原文地址:Linux内核源码分析--内核启动之(5)Image内核启动(rest_init函数)(Linux-3.0 ARMv7) 作者:tekkamanninja 转自:http://blog.chinaunix.net/uid-25909619-id-4938395.html 前面粗略分析start_kernel函数,此函数中基本上是对内存管理和各子系统的数据结构初始化.在内核初始化函数start_kernel执行到最后,就是调用rest_init函数,这个函数的主要使命就是创建并启动内核线

Spark的Master和Worker集群启动的源码分析

基于spark1.3.1的源码进行分析 spark master启动源码分析 1.在start-master.sh调用master的main方法,main方法调用 def main(argStrings: Array[String]) { SignalLogger.register(log) val conf = new SparkConf val args = new MasterArguments(argStrings, conf) val (actorSystem, _, _, _) =

Solr4.8.0源码分析(22)之 SolrCloud的Recovery策略(三)

Solr4.8.0源码分析(22)之 SolrCloud的Recovery策略(三) 本文是SolrCloud的Recovery策略系列的第三篇文章,前面两篇主要介绍了Recovery的总体流程,以及PeerSync策略.本文以及后续的文章将重点介绍Replication策略.Replication策略不但可以在SolrCloud中起到leader到replica的数据同步,也可以在用多个单独的Solr来实现主从同步.本文先介绍在SolrCloud的leader到replica的数据同步,下一篇

zg手册 之 python2.7.7源码分析(4)-- pyc字节码文件

什么是字节码 python解释器在执行python脚本文件时,对文件中的python源代码进行编译,编译的结果就是byte code(字节码) python虚拟机执行编译好的字节码,完成程序的运行 python会为导入的模块创建字节码文件 字节码文件的创建过程 当a.py依赖b.py时,如在a.py中import b python先检查是否有b.pyc文件(字节码文件),如果有,并且修改时间比b.py晚,就直接调用b.pyc 否则编译b.py生成b.pyc,然后加载新生成的字节码文件 字节码对象

LevelDB源码分析--Iterator

我们先来参考来至使用Iterator简化代码2-TwoLevelIterator的例子,略微修改希望能帮助更加容易立即,如果有不理解请各位看客阅读原文. 下面我们再来看一个例子,我们为一个书店写程序,书店里有许多书Book,每个书架(BookShelf)上有多本书. 类结构如下所示 class Book { private: string book_name_; }; class Shelf { private: vector<Book> books_; }; 如何遍历书架上所有的书呢?一种实

【Heritrix源码分析】Heritrix基本内容介绍

1.版本说明 (1)最新版本:3.3.0 (2)最新release版本:3.2.0 (3)重要历史版本:1.14.4 3.1.0及之前的版本:http://sourceforge.net/projects/archive-crawler/files/ 3.2.0及之后的版本:http://archive.org/ 由于国情需要,后者无法访问,因此本blog研究的是1.14.4版本. 2.官方材料 source:http://sourceforge.net/projects/archive-cra