一.问题在哪?

在配置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. 在centos集成服务器上安装imap扩展

    yum install libc-client-devel.x86_64(如果不行就yum install libc-client-devel)ln -s /usr/lib64/libc-client ...

  2. 绑定dropdownlist

    System.Data.SqlClient.SqlConnection sqlconn = new System.Data.SqlClient.SqlConnection(); sqlconn.C; ...

  3. Centos6.x 64位 安装JDK

    JDK下载地址: http://www.oracle.com/technetwork/cn/java/javase/downloads/jdk7-downloads-1880260-zhs.html ...

  4. 读取word文件.选择了TextParse

    待续! 代码还没分离出来.. 分离后会上传上来 不支持wps 文件 . ]]>

  5. COS访谈第十八期:陈天奇

    COS访谈第十八期:陈天奇 [COS编辑部按] 受访者:陈天奇      采访者:何通   编辑:王小宁 简介:陈天奇,华盛顿大学计算机系博士生,研究方向为大规模机器学习.他曾获得KDD CUP 20 ...

  6. KEIL C51中的_at_关键字

    绝对位置变量 变量可以在你的C程序中的绝对内存地址位于源模块使用_at_关键字.此功能的用法是: 类型 _ memory_space _ 变量名 _at _  常数 ; 其中:memory_space ...

  7. VIJOS P1543极值问题

    已知m.n为整数,且满足下列两个条件:① m.n∈1,2,…,K② (n^ 2-mn-m^2)^2=1编一程序,对给定K,求一组满足上述两个条件的m.n,并且使m^2+n^2的值最大.例如,若K=19 ...

  8. 【转】linux 原子整数操作详解

    原文网址:http://blog.csdn.net/hunanchenxingyu/article/details/8994379 printk(“%d\n”,atomic_read(&v)) ...

  9. UVA 11389 The Bus Driver Problem

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82842#problem/D In a city there are n bus ...

  10. Something broke! (Error 500)——reviewboard

    Something broke! (Error 500) 1.什么时候会出现? 不清楚,出现过几次 2.解决手段及方法: 更改/www_rb/conf/settings_local.py文件,将DEB ...