JAVA CAS单点登录之三:CAS代理模式演练

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://dba10g.blog.51cto.com/764602/1753244

前言

 JAVA CAS单点登录之一:搭建CAS服务器    

JAVA CAS单点登录之二:CAS普通模式1演练    

代理模式相相对上一节的普通模式,更加复杂了。但配置起来也会稍微有些差别。所谓难者不会,会者不难。如果遇到一个从来没有遇到的问题,解决起来也是非常棘手的,当然解决之后就不是事了。我就遇到了一个CAS 坑爹的错误。一步步按照别人的博客坐下来,普通模式部署没有多大问题,就是不知道为什么代理模式总是出错,搜遍了整个网络,也没找到问题所在,我就纳闷了,为什么就没有人 遇到过呢。还好,最后我使用了杀手锏,部署源码一步步跟踪找到了问题所在。

主要内容

搭建一整套环境.包括(cas-server ,cas proxy client,cas back-end app client)

一共三个Web应用。

具体参数  

涉及的所有参数都在我的实体机(WIN7)完成的。分别按照了3个TOMCAT服务端。

  • Tomcat6.0.36
  • JDK7
  • CAS Server版本:cas-server-3.5.3
  • CAS Client版本:cas-client-3.1.1
Cas Server 8888,443 配置见 JAVA CAS单点登录之一
Cas Proxy Client 8080 改造JAVA CAS单点登录之二的mywebapp1,改名为proxyClient
Cas Back-end Service Client 8070
改造JAVA CAS单点登录之二的

mywebapp2 

域名映射(C:\Windows\System32\drivers\etc\hosts)


1

2


127.0.0.1 hellocas1.com

127.0.0.1 hellocas2.com

主机名

zhaoguoyu-pc

操作步骤

  1. 修改cas Server端支持代理功能。

    就是这一步在其他文章中根本没有提到,我不知道是版本问题,还是什么问题。如果不配置,访问后台应用时会报 service.not.authorized.proxy异常。

1.1 修改 deployerConfigContext.xml文件支持代理


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

<bean

   id="serviceRegistryDao"

       class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl">

           <property name="registeredServices">

               <list>

                   <bean class="org.jasig.cas.services.RegexRegisteredService">

                       <property name="id" value="0" />

                       <property name="name" value="HTTP and IMAP" />

                       <property name="description" value="Allows HTTP(S) and IMAP(S) protocols" />

                       <property name="serviceId" value="^(https?|imaps?)://.*" />

                       <property name="evaluationOrder" value="10000001" />

                       <property name="allowedToProxy" value="true"/>

                   </bean>

                   <!--

                   Use the following definition instead of the above to further restrict access

                   to services within your domain (including subdomains).

                   Note that example.com must be replaced with the domain you wish to permit.

                   -->

                   <!--

                   <bean class="org.jasig.cas.services.RegexRegisteredService">

                       <property name="id" value="1" />

                       <property name="name" value="HTTP and IMAP on example.com" />

                       <property name="description" value="Allows HTTP(S) and IMAP(S) protocols on example.com" />

                       <property name="serviceId" value="^(https?|imaps?)://([A-Za-z0-9_-]+\.)*example\.com/.*" />

                       <property name="evaluationOrder" value="0" />

                   </bean>

                   -->

               </list>

           </property>

       </bean>

        就是添加 这个属性标签,


1

<property name="allowedToProxy" value="true"/>

我就是坑在这里了,坑了近3个晚上。,苦逼啊。现在回想起来真的太傻了。如果没这个插曲,我想CAS我可能又走马观花研究一两个晚上而已,正是这个插曲,燃起了我的斗志,所以也干脆写一个系列吧。

1.2 为了演练方便,修改 deployerConfigContext.xml文件,不需要安全请求。


1

2

3

<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"

   

p:httpClient-ref="httpClient" p:requireSecure="false"/>

就是添加这个属性


1

p:requireSecure="false"

通过上面2步的配置,CAS服务增加了代理,同时也支持普通连接访问了。

2.配置代理服务

在上一节的基础上,改造原来的web.xml,作为代理使用。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

<?xml version="1.0" encoding="UTF-8"?>

<web-app id="mywebapp" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 

  <display-name>mywebapp</display-name>

 

  <!-- Sign out not yet implemented -->

  <!--

      <filter>

          <filter-name>CAS Single Sign Out Filter</filter-name>

          <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>

      </filter>

  -->

 

  <filter>

    <filter-name>CAS Authentication Filter</filter-name>

    <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>

    <init-param>

      <param-name>casServerLoginUrl</param-name>

      <param-value>https://zhaoguoyu-pc/cas/login</param-value>

    </init-param>

    <init-param>

      <param-name>serverName</param-name>

      <param-value>http://zhaoguoyu-pc:8080</param-value>

    </init-param>

    <init-param>

      <param-name>renew</param-name>

      <param-value>false</param-value>

    </init-param>

    <init-param>

      <param-name>gateway</param-name>

      <param-value>false</param-value>

    </init-param>

  </filter>

 

  <filter>

    <filter-name>CAS Validation Filter</filter-name>

    <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>

    <init-param>

      <param-name>casServerUrlPrefix</param-name>

      <param-value>https://zhaoguoyu-pc/cas/</param-value>

    </init-param>

    <init-param>

      <param-name>serverName</param-name>

      <param-value>http://zhaoguoyu-pc:8080</param-value>

    </init-param>

 

    <init-param>

        <param-name>proxyCallbackUrl</param-name>

        <param-value>http://zhaoguoyu-pc:8080/mywebapp/proxyCallback</param-value>

    </init-param>

    <init-param>

        <param-name>proxyReceptorUrl</param-name>

        <param-value>/proxyCallback</param-value>

    </init-param>

 

  </filter>

 

  <filter>

    <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>

    <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>

  </filter>

 

  <filter>

    <filter-name>CAS Assertion Thread Local Filter</filter-name>

    <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>

  </filter>

 

  <!-- ************************* -->

 

  <!-- Sign out not yet implemented -->

  <!--

      <filter-mapping>

          <filter-name>CAS Single Sign Out Filter</filter-name>

          <url-pattern>/*</url-pattern>

      </filter-mapping>

  -->

  <filter-mapping>

    <filter-name>CAS Validation Filter</filter-name>

    <url-pattern>/proxyCallback</url-pattern>

  </filter-mapping>

 

  <filter-mapping>

    <filter-name>CAS Authentication Filter</filter-name>

    <url-pattern>/protected/*</url-pattern>

  </filter-mapping>

 

  <filter-mapping>

    <filter-name>CAS Validation Filter</filter-name>

    <url-pattern>/*</url-pattern>

  </filter-mapping>

 

  <filter-mapping>

    <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>

    <url-pattern>/*</url-pattern>

  </filter-mapping>

 

  <filter-mapping>

    <filter-name>CAS Assertion Thread Local Filter</filter-name>

    <url-pattern>/*</url-pattern>

  </filter-mapping>

 

 

 

  <!--  *********************** -->

 

  <!-- Sign out not yet implemented -->

  <!--

      <listener>

          <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>

      </listener>

  -->

 

  <!--  *********************** -->

 

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

 

</web-app>

修改的内容如下

1.为Cas20ProxyReceivingTicketValidationFilter增加2个配置元素

    <init-param>
        <param-name>proxyCallbackUrl</param-name>
        <param-value>http://zhaoguoyu-pc:8080/proxyClient/proxyCallback</param-value>
    </init-param>
    <init-param>
        <param-name>proxyReceptorUrl</param-name>
        <param-value>/proxyCallback</param-value>
    </init-param>

2.增加映射URL(注意顺序),一定要在其他filter的前面


1

2

3

4

  <filter-mapping>

    <filter-name>CAS Validation Filter</filter-name>

    <url-pattern>/proxyCallback</url-pattern>

  </filter-mapping>

到这儿,可以作为一个普通服务可以作为代理使用了。

3.复制改名另外一个普通应用,作为后台应用(back-end service)

修改web.xml

   


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

 <filter>

        <filter-name>CAS Validation Filter</filter-name>

        <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>

        <init-param>

            <param-name>casServerUrlPrefix</param-name>

            <param-value>https://zhaoguoyu-pc/cas/</param-value>

        </init-param>

        <init-param>

            <param-name>serverName</param-name>

            <param-value>http://hellocas2.com:8070</param-value>

        </init-param>

        <init-param>

            <param-name>acceptAnyProxy</param-name>

            <param-value>true</param-value>

        </init-param>    

    <init-param

        <param-name>redirectAfterValidation</param-name>

        <param-value>false</param-value>

    </init-param>    

    </filter>

添加了acceptAnyProxy 和redirectAfterValidation参数。支持接收代理

4.在proxy 应用下添加测试的Servlet

ProxyTestServlet HttpServlet {
    doPost(HttpServletRequest request, HttpServletResponse response) ServletException, IOException {
        String serviceUrl = "http://hellocas2.com:8070/mywebapp2/protected/";
        Assertion assertion = AssertionHolder.();
        String proxyTicket = assertion.getPrincipal().getProxyTicketFor(serviceUrl);
        URL url = URL(serviceUrl + + proxyTicket);
        HttpURLConnection conn = ;
        {
            conn = (HttpURLConnection) url.openConnection();
            responseCode = conn.getResponseCode();
            String responseMessage = conn.getResponseMessage();
            System..println(+responseCode);
            System..println();
            System..println();
            System..println(responseMessage);
        } (Exception ex) {
            ex.printStackTrace();
        } {
            (conn != ) {
                conn.disconnect();
            }
        }
    }

    doGet(HttpServletRequest request, HttpServletResponse response) ServletException, IOException {
        doPost(request, response);
    }
}

5.测试验证

前提:分别启动CAS-server,Cas-proxy,Cas-backend client

5.1 输入地址,http://zhaoguoyu-pc:8080/proxyClient。

5.2 输入用户名和密码

5.3 访问servlet

http://zhaoguoyu-pc:8080/proxyClient/proxyTestServlet

经过确认,反悔代码为200,和OK。表示测试通过。

如果想详细链接关于代理模式的原理,请参考

http://my.oschina.net/ichatter/blog/129642

http://blog.csdn.net/emon123/article/details/6285549

http://www.blogjava.net/security/archive/2006/04/26/SSO_CASProxy.html

http://www.myexception.cn/software-architecture-design/644728.html

http://init-life.com/web/2014/11/12/cas-workflows/

http://www.mytju.com/classcode/news_readNews.asp?newsID=503

https://wiki.jasig.org/display/CASC/CAS+Client+for+Java+3.1。

部署期间,我遇到这个坑爹的异常

<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>

    <cas:authenticationFailure code='service.not.authorized.proxy'>

        service.not.authorized.proxy

    </cas:authenticationFailure>

</cas:serviceResponse>

This is because proxy authn is turned off by default. Set the proxy flag in 
your service registry and off it goes.

感觉哪儿少配了个参数,硬是搜遍了大量博客,竟然没找到。最后自己看源码,一步步跟踪出来的。

本文出自 “简单” 博客,请务必保留此出处http://dba10g.blog.51cto.com/764602/1753244

时间: 2024-08-23 16:00:47

JAVA CAS单点登录之三:CAS代理模式演练的相关文章

JAVA CAS单点登录之四:CAS服务器增加JDBC访问能力

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://dba10g.blog.51cto.com/764602/1753680 经过前面说明,已经完成了CAS服务器的搭建,代理客户端的搭建以及普通客户端,back-end-service客户端的搭建.如果不明白的,参照如下链接. JAVA CAS单点登录之一:搭建CAS服务器  JAVA CAS单点登录之二:CAS普通模式1演练 JAVA CAS单点登录之三:CAS代理模式演练  现

CAS单点登录时AJAX页面刷新无反应(302 Moved Temporarily)

最近使用CAS做单点认证服务时发现过大概二十分钟后就发现凡是异步方式刷新页面就无反应了(由于使用EasyUI框架,所以页面刷新基于ajax+div方式),刚开始一直认为是CAS服务端超时的问题,查看了各个配置,网上也参考了许多帖子,一直没有解决,今天无意想起来是不是session过期了呢,因为单点登录客户端没有配置任何session有效时长,也就是说客户端的session时长为tomcat默认时长(网上有人说Tomcat默认session有效期为30分钟,而现在发现的是大概20分钟后就会出现用a

JAVA CAS单点登录之二:CAS普通模式1演练

前言 经过上一JAVA CAS单点登录之一:搭建CAS服务器 这一章,CAS服务器已经搭建好了.当然这时候的CAS服务器仅仅是最初版本的.比如密码验证,页面美观度都需要进一步调整.但这都是无关紧要的. 最主要的是先把整个一套认证流程走下来,至于完善的工作,都是没个点的工作了,相对比较简单. 主要内容    1. 新建一个web应用mywebapp1,测试与CAS服务器的认证效果     2.如果上一步骤1认证成功的话,将mywebapp1复制一份,调整若干参数,继续测试.     如果步骤1,步

CAS单点登录(SSO)完整教程

CAS单点登录(SSO)完整教程(2012-02-01更新) 一.教程说明 前言 教程目的:从头到尾细细道来单点登录服务器及客户端应用的每个步骤 单点登录(SSO):请看百科解释猛击这里打开 本教程使用的SSO服务器是Yelu大学研发的CAS(Central Authentication Server), 官网:http://www.jasig.org/cas 本教程环境: Tomcat6.0.29 JDK6 CAS Server版本:cas-server-3.4.3.1.cas-server-

单点登录之CAS SSO从入门到精通(第一天)

啊......it's quite a long time. 好久没更新博客了,有一年之久了,一直在忙于公司的一些项目.2014年到2015年工作太忙,我也接触到了新的领域,认识了新的同事. 对于一些经常跟我博客的读者们深深说一声抱歉. 同时,也在新的一年将到之际,祝各位新春愉快,羊年洋洋洋. 好了,废话少说,开始我们架构师之路的新的历程,SSO-单点登录. 另外想以此SSO系列教程献给我那身体不太好的同事-小白同志,祝小白同志身体一直健康                            

CAS单点登录之mysql数据库用户验证及常见问题

前面已经介绍了CAS服务器的搭建,详情见:搭建CAS单点登录服务器.然而前面只是简单地介绍了服务器的搭建,其验证方式是原始的配置文件的方式,这显然不能满足日常的需求.下面介绍下通过mysql数据库认证的方式. 一.CAS认证之mysql数据库认证 1.在mysql中新建一个cas数据库并创建user表 CREATE DATABASE /*!32312 IF NOT EXISTS*/`cas` /*!40100 DEFAULT CHARACTER SET gbk */; USE `cas`; /*

java-关于CAS单点登录的用户认证

问题描述 关于CAS单点登录的用户认证 现有多个系统web1,web2,web3... 用户张三,在web1里用户名密码是user1/123,在web2里用户名密码是zhangsan/456,在web3里用户名密码是abc/789-- 这些多个系统的用户名密码存放在不同数据库中,但是每个数据库里都有"工号"这个字段,且为必填项. 现在将这多个系统用CAS做单点登录,这多个数据库如何通过"工号"这个字段统一? 刚看到的一个思路: 单对多模式:一个用户使用不同凭证登录不

java-【急】求大神帮帮忙,CAS单点登录问题,登录成功后controller收不到请求(要哭了)

问题描述 [急]求大神帮帮忙,CAS单点登录问题,登录成功后controller收不到请求(要哭了) 首先说下问题,我们的项目之前SSO单点登录一直用的http的方式, 这一块登录一直都是正常的,现在要切上正式环境了,SSO服务器那边就改用了https的方式SSO配置如下: <listener> <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-cla

SpringSecurity+JPA+CAS单点登录

问题描述 SpringSecurity+JPA+CAS单点登录错误信息如下:ERRORContextLoader:220-Contextinitializationfailedorg.springframework.beans.factory.BeanDefinitionStoreException:UnexpectedexceptionparsingXMLdocumentfromServletContextresource[/WEB-INF/classes/applicationContext