一.问题在哪?

在配置cas-client中,有这么一段配置:

    <filter>
<filter-name>CAS Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>https://demo.testcas.com/cas/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://app1.testcas.com</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

详情请参考:单点登录CAS使用记(二):部署CAS服务器以及客户端

意思大概是:拦截客户端的所有请求,如果发现还没有通过CAS认证中心认证,则强行重定向到Cas-server的登录页面。

这里面有一个问题?

即:客户端所有请求都被拦截并且跳转,包括静态资源,静态页面等,这是不合理的。

二.如何解决?

2.1 百度下大多数的解决方案

扩展CASFilter过滤器,加上一个排除指定URL的功能,然后在web.xml配置中,手动添加需要排除的所有URL。

这确是一种解决方法,但是过于繁琐,而且在网站请求地址过多的情况下,稍有不慎,就会出现遗漏。

如果这是你想要的,请另行百度。

2.2 我的解决方案:

因为我是要整合两个比较成熟的项目,换言之,就是这两个项目已经自带了用户登录验证、用户权限验证、不拦截静态资源等处理。

所以我是不是可以利用原有项目的拦截逻辑?

原有项目功能简述:

1.项目采用了SpringMVC框架

2.对所有静态资源放行,例如:css、js、img等

例如:web.xml中配置如下(激活Tomcat的defaultServlet来处理静态文件)

<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>

3.自定义了一个@RequestSecurity的注解,并对所有有权限控制的方法加上该注解

4.用户发出请求->被拦截器拦截->拦截器判断该用户请求方法是否被标注了@RequestSecurity

IF:如果有该注解,继续判断用户是否已经登录(通过session是否存在来判断),如果没有登录,则重定向到登录页面进行登录。

ELSE:如果没有该注解,证明该资源可随意访问,直接放行。

注意上文红色描述,所以,我只要稍微改造一下原有项目的拦截器,让他不是直接跳转到原有登录页面,跳转到一个特定的请求地址,让cas-filter拦截只拦截这一个请求就可以了。

三.改造验证

第一步:修改原有项目拦截器

项目中,有这么一段SpringMVC拦截器配置(伪代码展示)

    <mvc:interceptors>
<bean class="com.xxxx.interceptor.SecurityInterceptor">
<property name="redirectUrl">
<value>/login</value>
</property>
       ...
</bean>
</mvc:interceptors>

意思就是,一旦拦截到用户未登录,直接跳转到doLogin方法,让用户登录。

我对他修改如下:

    <mvc:interceptors>
<bean class="com.xxxx.interceptor.SecurityInterceptor">
<property name="redirectUrl">
<value>/casLogin</value>
</property>
       ...
</bean>
</mvc:interceptors>

意思就是:一旦拦截到用户未登录,跳转到doCasLogin方法

第二步:新增casLogin方法

    @RequestSecurity
@RequestMapping(value = "casLogin", method = { RequestMethod.GET,
RequestMethod.POST })
public String casLogin()
{
return "welcome";
}

意思就是:如果用户未登录,会被强制重定向到本方法。

第三步:修改cas-client的拦截器Cas-Filter的拦截范围

    <filter>
<filter-name>CAS Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>https://demo.testcas.com/cas/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://app1.testcas.com</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/casLogin</url-pattern>
</filter-mapping>

意思就是:CAS Filter只拦截casLogin请求,其他请求一律不拦截。一旦拦截到casLogin请求,说明用户暂未登录,则强制重定向到Cas-Server的登录页面。

到这里,Cas-client不拦截静态资源处理就改造好了。

 

但是,如果只做上面3步,进行测试的话,浏览器有可能会报“此页面包含重定向循环”的错误提示,并不能真正登入页面。

原因看以下流程:

1.首先被重定向到了Cas认证中心

2.用户输入用户名密码等,点击登录通过了Cas登陆认证

3.再一次被重定向回/casLogin,

4.又被Cas-Fliter拦截,不过此时Cas-Fliter发现用户已经通过了Cas认证中心认证,不做重定向处理,继续后续处理。

5.因为casLogin方法标注了@RequestSecurity,所以又被原有项目的mvc:interceptors拦截,拦截器发现用户未登录(通过session是否为空来判断)

6.又被强行重定向会casLogin,然后又回到了4,陷入了无穷的循环中...

如何打破此重定向循环?

关键在于第5步,当Cas-Server重定向回来时,会带回通过认证的用户信息。

取得方式如下:

AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();
String username = principal.getName();

这时,在过滤器判断用户是否已经登录前,先行判断如果是Cas-server重定向过来的请求,并且principal、username存在,则把用户信息写入客户端UserSession中。

然后再判断发现,已经写入了UserSession了,说明登录成功,直接登录welcome页面。

登录成功。

注:本文所记录的是自己摸索所得,并不敢完全保证程序逻辑的严谨性,如果您发现有所纰漏,请给予批评指正。


单点登录CAS使用记系列:

单点登录CAS使用记(五):cas-client不拦截静态资源以及无需登录的请求。的更多相关文章

  1. 单点登录CAS使用记(二):部署CAS服务器以及客户端

    CAS-Server下载地址:https://www.apereo.org/projects/cas/download-cas CAS-Client下载地址:http://developer.jasi ...

  2. 单点登录CAS使用记(一):前期准备以及为CAS-Server配置SSL协议

    知识点: SSO:单点登录(Single Sign On),是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. CAS:耶 ...

  3. 单点登录CAS使用记(三):实现自定义验证用户登录

    问题: CAS自带的用户验证逻辑太过简单,如何像正常网站一样,通过验证DB中的用户数据,来验证用户以及密码的合法性呢? 方案1:CAS默认的JDBC扩展方案: CAS自带了两种简单的通过JDBC方式验 ...

  4. 单点登录CAS使用记(四):为登录页面加上验证码

    CAS默认的登录页面样式如下,只有用户名与密码两项验证项目. 现在需要为首页登录加上验证码功能. 第一步:首页对默认登录页面的样式进行了调整,使其看上去还算美观. 在页面上加上了验证码项目. 第二步: ...

  5. 单点登录CAS使用记(六):单点登出、单点注销

    单点登出基本上没有啥配置 直接在原来logout的时候,重定向到Cas-Server的logout方法 @RequestSecurity @RequestMapping(value = "l ...

  6. 单点登录CAS使用记(七):关于服务器超时以及客户端超时的分析

    我的预想情况 一般情况下,当用户登录一个站点后,如果长时间没有发生任何动作,当用户再次点击时,会被强制登出并且跳转到登录页面, 提醒用户重新登录.现在我已经为站点整合了CAS,并且已经实现了单点登录以 ...

  7. 单点登录CAS使用记(八):使用maven的overlay实现无侵入的改造CAS

    前期在学习CAS部署的过程中,都是网上各种教程,各种方案不停的尝试. 期间各种侵入改源码,时间久了,改了哪个文件,改了哪段配置,增加了哪段代码,都有可能混淆不清了. 而且最大的问题是,万一换个人来维护 ...

  8. SpringMVC——拦截器,过滤器实现登录拦截

    一.拦截器与过滤器的区别 1.过滤器 依赖于servlet容器.在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次.使用过滤器的目的是用来做一些过滤操 ...

  9. (转)基于CAS实现单点登录(SSO):cas client端的退出问题

    出处:http://blog.csdn.net/tch918/article/details/22276627 自从CAS 3.4就很好的支持了单点注销功能,配置也很简单. 之前版本因为在CAS服务器 ...

随机推荐

  1. java 属性

    //非静态类 不能定义静态属性/方法/静态类, 可以定义静态常量属性. public class A{ public class B{ public static String  _str; //❌, ...

  2. Spring ApplicationContext的国际化支持

    ApplicationContext接口继承MessageSource接口,因此具备国际化功能.下面是MessageSource接口定义的三个国际化方法. >String getMessage( ...

  3. 在CentOS6上使用YUM安装Mysql5.5.x

    1.安装MySQL 5.5.x的yum源: rpm -Uvh http://repo.webtatic.com/yum/centos/5/latest.rpm 2.安装MySQL客户端的支持包: yu ...

  4. Fetcher类的工作流程

    Fetcher类工作流程: FileInputFormat.addInputPath(job, new Path(segment, CrawlDatum.GENERATE_DIR_NAME)); jo ...

  5. 查看ASM 使用率

    有两种方法: 1.查看v$asm_diskgroup视图 SQL> select group_number,name,total_mb,free_mb from v$asm_diskgroup; ...

  6. 【动态规划】XMU 1583 Sequence

    题目链接: http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1583 题目大意: T组数据,对于n(n<=6000)给定序列Xn(Xn<= ...

  7. STL_iterator迭代器(2)——几种迭代器对象的用法

    要学会使用迭代器和容器以及算法,需要学习下面的新技术. 一.流和迭代器 本书的很多例子程序使用I/O流语句来读写数据.例如: int value; cout << "Enter ...

  8. iOS应用内语言切换功能

    当我们的应用仅仅面向国内用户群,一般仅支持一种语言--中文就可以了.当面向国外用户时就需要进行国际化了,不仅仅是语言的转变,也可能包括设计风格,页面布局.交互效果的转变,如微信,微博,QQ这类应用都有 ...

  9. linux 启动network后报错:device eth0 does not seem to be present, delaying initialization

    问题背景: 在vsphere client中部署ovf模板后启动linux 的network后提示:device eth0 does not seem to be present, delaying ...

  10. 关于PHP的curl开启问题 (转)

    今天在做一个新浪登录功能,新浪提供的PHP SDK里需要用到curl_init()函数,在调试的时候报找不到curl_init()的方法. 经搜索得知需要开启curl的php扩展,那curl又是什么呢 ...