天天看点

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

前言

<a href="http://dba10g.blog.51cto.com/764602/1753086" target="_blank"> java cas单点登录之一:搭建cas服务器    </a>

<a href="http://dba10g.blog.51cto.com/764602/1753151" target="_blank">java cas单点登录之二:cas普通模式1演练    </a>

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

主要内容

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

一共三个web应用。

具体参数  

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

tomcat6.0.36

jdk7

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

<code>127.0.0.1 hellocas1.com</code>

<code>127.0.0.1 hellocas2.com</code>

主机名

zhaoguoyu-pc

操作步骤

修改cas server端支持代理功能。

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

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

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

<code>&lt;</code><code>bean</code>

<code>   </code><code>id</code><code>=</code><code>"serviceregistrydao"</code>

<code>       </code><code>class</code><code>=</code><code>"org.jasig.cas.services.inmemoryserviceregistrydaoimpl"</code><code>&gt;</code>

<code>           </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"registeredservices"</code><code>&gt;</code>

<code>               </code><code>&lt;</code><code>list</code><code>&gt;</code>

<code>                   </code><code>&lt;</code><code>bean</code> <code>class</code><code>=</code><code>"org.jasig.cas.services.regexregisteredservice"</code><code>&gt;</code>

<code>                       </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"id"</code> <code>value</code><code>=</code><code>"0"</code> <code>/&gt;</code>

<code>                       </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"name"</code> <code>value</code><code>=</code><code>"http and imap"</code> <code>/&gt;</code>

<code>                       </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"description"</code> <code>value</code><code>=</code><code>"allows http(s) and imap(s) protocols"</code> <code>/&gt;</code>

<code>                       </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"serviceid"</code> <code>value</code><code>=</code><code>"^(https?|imaps?)://.*"</code> <code>/&gt;</code>

<code>                       </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"evaluationorder"</code> <code>value</code><code>=</code><code>"10000001"</code> <code>/&gt;</code>

<code>                       </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"allowedtoproxy"</code> <code>value</code><code>=</code><code>"true"</code><code>/&gt;</code>

<code>                   </code><code>&lt;/</code><code>bean</code><code>&gt;</code>

<code>                   </code><code>&lt;!--</code>

<code>                   </code><code>use the following definition instead of the above to further restrict access</code>

<code>                   </code><code>to services within your domain (including subdomains).</code>

<code>                   </code><code>note that example.com must be replaced with the domain you wish to permit.</code>

<code>                   </code><code>--&gt;</code>

<code>                   </code><code>&lt;bean class="org.jasig.cas.services.regexregisteredservice"&gt;</code>

<code>                       </code><code>&lt;property name="id" value="1" /&gt;</code>

<code>                       </code><code>&lt;property name="name" value="http and imap on example.com" /&gt;</code>

<code>                       </code><code>&lt;property name="description" value="allows http(s) and imap(s) protocols on example.com" /&gt;</code>

<code>                       </code><code>&lt;property name="serviceid" value="^(https?|imaps?)://([a-za-z0-9_-]+\.)*example\.com/.*" /&gt;</code>

<code>                       </code><code>&lt;property name="evaluationorder" value="0" /&gt;</code>

<code>                   </code><code>&lt;/bean&gt;</code>

<code>               </code><code>&lt;/</code><code>list</code><code>&gt;</code>

<code>           </code><code>&lt;/</code><code>property</code><code>&gt;</code>

<code>       </code><code>&lt;/</code><code>bean</code><code>&gt;</code>

        就是添加 这个属性标签,

<code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"allowedtoproxy"</code> <code>value</code><code>=</code><code>"true"</code><code>/&gt;</code>

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

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

<code>&lt;</code><code>bean</code> <code>class</code><code>=</code><code>"org.jasig.cas.authentication.handler.support.httpbasedservicecredentialsauthenticationhandler"</code>

<code>  </code> 

<code>p:httpclient-ref</code><code>=</code><code>"httpclient"</code> <code>p:requiresecure</code><code>=</code><code>"false"</code><code>/&gt;</code>

就是添加这个属性

<code>p:requiresecure="false"</code>

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

2.配置代理服务

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

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

<code>&lt;?</code><code>xml</code> <code>version</code><code>=</code><code>"1.0"</code> <code>encoding</code><code>=</code><code>"utf-8"</code><code>?&gt;</code>

<code>&lt;</code><code>web-app</code> <code>id</code><code>=</code><code>"mywebapp"</code> <code>version</code><code>=</code><code>"2.4"</code> <code>xmlns</code><code>=</code><code>"http://java.sun.com/xml/ns/j2ee"</code> <code>xmlns:xsi</code><code>=</code><code>"http://www.w3.org/2001/xmlschema-instance"</code> <code>xsi:schemalocation</code><code>=</code><code>"http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"</code><code>&gt;</code>

<code>  </code><code>&lt;</code><code>display-name</code><code>&gt;mywebapp&lt;/</code><code>display-name</code><code>&gt;</code>

<code>  </code><code>&lt;!-- sign out not yet implemented --&gt;</code>

<code>  </code><code>&lt;!--</code>

<code>      </code><code>&lt;filter&gt;</code>

<code>          </code><code>&lt;filter-name&gt;cas single sign out filter&lt;/filter-name&gt;</code>

<code>          </code><code>&lt;filter-class&gt;org.jasig.cas.client.session.singlesignoutfilter&lt;/filter-class&gt;</code>

<code>      </code><code>&lt;/filter&gt;</code>

<code>  </code><code>--&gt;</code>

<code>  </code><code>&lt;</code><code>filter</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>filter-name</code><code>&gt;cas authentication filter&lt;/</code><code>filter-name</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>filter-class</code><code>&gt;org.jasig.cas.client.authentication.authenticationfilter&lt;/</code><code>filter-class</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>init-param</code><code>&gt;</code>

<code>      </code><code>&lt;</code><code>param-name</code><code>&gt;casserverloginurl&lt;/</code><code>param-name</code><code>&gt;</code>

<code>      </code><code>&lt;</code><code>param-value</code><code>&gt;https://zhaoguoyu-pc/cas/login&lt;/</code><code>param-value</code><code>&gt;</code>

<code>    </code><code>&lt;/</code><code>init-param</code><code>&gt;</code>

<code>      </code><code>&lt;</code><code>param-name</code><code>&gt;servername&lt;/</code><code>param-name</code><code>&gt;</code>

<code>      </code><code>&lt;</code><code>param-value</code><code>&gt;http://zhaoguoyu-pc:8080&lt;/</code><code>param-value</code><code>&gt;</code>

<code>      </code><code>&lt;</code><code>param-name</code><code>&gt;renew&lt;/</code><code>param-name</code><code>&gt;</code>

<code>      </code><code>&lt;</code><code>param-value</code><code>&gt;false&lt;/</code><code>param-value</code><code>&gt;</code>

<code>      </code><code>&lt;</code><code>param-name</code><code>&gt;gateway&lt;/</code><code>param-name</code><code>&gt;</code>

<code>  </code><code>&lt;/</code><code>filter</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>filter-name</code><code>&gt;cas validation filter&lt;/</code><code>filter-name</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>filter-class</code><code>&gt;org.jasig.cas.client.validation.cas20proxyreceivingticketvalidationfilter&lt;/</code><code>filter-class</code><code>&gt;</code>

<code>      </code><code>&lt;</code><code>param-name</code><code>&gt;casserverurlprefix&lt;/</code><code>param-name</code><code>&gt;</code>

<code>      </code><code>&lt;</code><code>param-value</code><code>&gt;https://zhaoguoyu-pc/cas/&lt;/</code><code>param-value</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>param-name</code><code>&gt;proxycallbackurl&lt;/</code><code>param-name</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>param-value</code><code>&gt;http://zhaoguoyu-pc:8080/mywebapp/proxycallback&lt;/</code><code>param-value</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>param-name</code><code>&gt;proxyreceptorurl&lt;/</code><code>param-name</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>param-value</code><code>&gt;/proxycallback&lt;/</code><code>param-value</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>filter-name</code><code>&gt;cas httpservletrequest wrapper filter&lt;/</code><code>filter-name</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>filter-class</code><code>&gt;org.jasig.cas.client.util.httpservletrequestwrapperfilter&lt;/</code><code>filter-class</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>filter-name</code><code>&gt;cas assertion thread local filter&lt;/</code><code>filter-name</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>filter-class</code><code>&gt;org.jasig.cas.client.util.assertionthreadlocalfilter&lt;/</code><code>filter-class</code><code>&gt;</code>

<code>  </code><code>&lt;!-- ************************* --&gt;</code>

<code>      </code><code>&lt;filter-mapping&gt;</code>

<code>          </code><code>&lt;url-pattern&gt;/*&lt;/url-pattern&gt;</code>

<code>      </code><code>&lt;/filter-mapping&gt;</code>

<code>  </code><code>&lt;</code><code>filter-mapping</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>url-pattern</code><code>&gt;/proxycallback&lt;/</code><code>url-pattern</code><code>&gt;</code>

<code>  </code><code>&lt;/</code><code>filter-mapping</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>url-pattern</code><code>&gt;/protected/*&lt;/</code><code>url-pattern</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>url-pattern</code><code>&gt;/*&lt;/</code><code>url-pattern</code><code>&gt;</code>

<code>  </code><code>&lt;!--  *********************** --&gt;</code>

<code>      </code><code>&lt;listener&gt;</code>

<code>          </code><code>&lt;listener-class&gt;org.jasig.cas.client.session.singlesignouthttpsessionlistener&lt;/listener-class&gt;</code>

<code>      </code><code>&lt;/listener&gt;</code>

<code>  </code><code>&lt;</code><code>welcome-file-list</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>welcome-file</code><code>&gt;index.jsp&lt;/</code><code>welcome-file</code><code>&gt;</code>

<code>  </code><code>&lt;/</code><code>welcome-file-list</code><code>&gt;</code>

<code>&lt;/</code><code>web-app</code><code>&gt;</code>

修改的内容如下

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

    &lt;init-param&gt;

        &lt;param-name&gt;proxycallbackurl&lt;/param-name&gt;

        &lt;param-value&gt;http://zhaoguoyu-pc:8080/proxyclient/proxycallback&lt;/param-value&gt;

    &lt;/init-param&gt;

        &lt;param-name&gt;proxyreceptorurl&lt;/param-name&gt;

        &lt;param-value&gt;/proxycallback&lt;/param-value&gt;

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

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

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

修改web.xml

<code> </code><code>&lt;</code><code>filter</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>filter-name</code><code>&gt;cas validation filter&lt;/</code><code>filter-name</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>filter-class</code><code>&gt;org.jasig.cas.client.validation.cas20proxyreceivingticketvalidationfilter&lt;/</code><code>filter-class</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>init-param</code><code>&gt;</code>

<code>            </code><code>&lt;</code><code>param-name</code><code>&gt;casserverurlprefix&lt;/</code><code>param-name</code><code>&gt;</code>

<code>            </code><code>&lt;</code><code>param-value</code><code>&gt;https://zhaoguoyu-pc/cas/&lt;/</code><code>param-value</code><code>&gt;</code>

<code>        </code><code>&lt;/</code><code>init-param</code><code>&gt;</code>

<code>            </code><code>&lt;</code><code>param-name</code><code>&gt;servername&lt;/</code><code>param-name</code><code>&gt;</code>

<code>            </code><code>&lt;</code><code>param-value</code><code>&gt;http://hellocas2.com:8070&lt;/</code><code>param-value</code><code>&gt;</code>

<code>            </code><code>&lt;</code><code>param-name</code><code>&gt;acceptanyproxy&lt;/</code><code>param-name</code><code>&gt;</code>

<code>            </code><code>&lt;</code><code>param-value</code><code>&gt;true&lt;/</code><code>param-value</code><code>&gt;</code>

<code>        </code><code>&lt;/</code><code>init-param</code><code>&gt;    </code>

<code>    </code><code>&lt;</code><code>init-param</code><code>&gt; </code>

<code>        </code><code>&lt;</code><code>param-name</code><code>&gt;redirectaftervalidation&lt;/</code><code>param-name</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>param-value</code><code>&gt;false&lt;/</code><code>param-value</code><code>&gt;</code>

<code>    </code><code>&lt;/</code><code>init-param</code><code>&gt;    </code>

<code>    </code><code>&lt;/</code><code>filter</code><code>&gt;</code>

添加了acceptanyproxy 和redirectaftervalidation参数。支持接收代理

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

5.测试验证

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

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

5.2 输入用户名和密码

5.3 访问servlet

<a href="http://zhaoguoyu-pc:8080/proxyclient/proxytestservlet" target="_blank">http://zhaoguoyu-pc:8080/proxyclient/proxytestservlet</a>

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

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

<a href="http://my.oschina.net/ichatter/blog/129642" target="_blank">http://my.oschina.net/ichatter/blog/129642</a>

<a href="http://blog.csdn.net/emon123/article/details/6285549" target="_blank">http://blog.csdn.net/emon123/article/details/6285549</a>

<a href="http://www.blogjava.net/security/archive/2006/04/26/sso_casproxy.html" target="_blank">http://www.blogjava.net/security/archive/2006/04/26/sso_casproxy.html</a>

<a href="http://www.myexception.cn/software-architecture-design/644728.html" target="_blank">http://www.myexception.cn/software-architecture-design/644728.html</a>

<a href="http://init-life.com/web/2014/11/12/cas-workflows/" target="_blank">http://init-life.com/web/2014/11/12/cas-workflows/</a>

<a href="http://www.mytju.com/classcode/news_readnews.asp?newsid=503" target="_blank">http://www.mytju.com/classcode/news_readnews.asp?newsid=503</a>

<a href="https://wiki.jasig.org/display/casc/cas+client+for+java+3.1" target="_blank">https://wiki.jasig.org/display/casc/cas+client+for+java+3.1。</a>

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

    &lt;cas:authenticationfailure code='service.not.authorized.proxy'&gt;

        service.not.authorized.proxy

    &lt;/cas:authenticationfailure&gt;

&lt;/cas:serviceresponse&gt;

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