Spring Security实践(三):通过CAS实现SSO

SSO(单点登录)要求同一个用户在使用不同的应用时,只需要登录一次即可。关于SSO系统的详细介绍此处不涉及。Spring Security提供了良好的接口和CAS进行整合。CAS是一个SSO系统,分为Client和Server,Server来完成用户的认证,Client放在应用端来和Server进行交互获取用户的认证信息。

本文主要用来指导在Spring Security框架下配置CAS完成SSO功能。达到如下目的:

  • 对未授权的WEB请求的访问都会重定向到CAS Server上进行验证
  • 验证通过的用户可以访问WEB资源和提交WEB请求
  • A应用登录后,相同的用户用相同的浏览器登录B应用(A和B都是通过CAS Server进行授权),不需要再进行验证。
  • 可以对单应用进行登出,也可以登出用户
  • 提供CSRF保护

关于CAS Server的安装和配置,本文档不做说明,可以参考《CAS Server部署指南》文档。

配置

为了使用CAS的功能,需要安装security支持CAS的jar包,修改pom.xml如下:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-cas</artifactId>
    <version>4.0.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.jasig.cas.client</groupId>
    <artifactId>cas-client-core</artifactId>
    <version>3.3.3</version>
    <scope>compile</scope>
</dependency>

Spring-security.xml的配置如下:

<!-- CAS Configuration-->
<bean id="serviceProperties"
      class="org.springframework.security.cas.ServiceProperties">
    <property name="service"
              value="http://localhost:8080/login/cas"/>
    <property name="sendRenew" value="false"/>
</bean>
<!-- CAS Filter-->
<security:authentication-manager alias="authenticationManager">
    <security:authentication-provider ref="casAuthenticationProvider" />
</security:authentication-manager>
<bean id="casAuthenticationProvider"
      class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
    <property name="authenticationUserDetailsService">
        <bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
            <constructor-arg ref="userService" />
        </bean>
    </property>
    <property name="serviceProperties" ref="serviceProperties" />
    <property name="ticketValidator">
        <bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
            <constructor-arg index="0" value="https://ssomanage.test.com:8443/cas" />
        </bean>
    </property>
    <property name="key" value="casAuthProviderKey"/>
</bean>
<security:user-service id="userService">
    <security:user name="xiaof" password="post-it" authorities="ROLE_ADMIN,ROLE_USER" />
    <security:user name="test1" password="" authorities="ROLE_USER" />
</security:user-service>
<bean id="casFilter"
      class="org.springframework.security.cas.web.CasAuthenticationFilter">
    <property name="authenticationManager" ref="authenticationManager"/>
</bean>
<bean id="casEntryPoint"
      class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
    <property name="loginUrl" value="https://ssomanage.test.com:8443/cas/login"/>
    <property name="serviceProperties" ref="serviceProperties"/>
</bean>
<!-- CSRF Configuration-->
<bean id="csrfTokenFilter" class="com.test.cloud.security.CsrfTokenFilter"/>
<!-- CAS Logout Configuration-->
    <!-- This filter handles a Single Logout Request from the CAS Server -->
<bean id="singleLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter"/>
<!-- This filter redirects to the CAS Server to signal Single Logout should be performed -->
<bean id="requestSingleLogoutFilter"
      class="org.springframework.security.web.authentication.logout.LogoutFilter">
    <constructor-arg value="https://ssomanage.test.com:8443/cas/logout"/>
    <constructor-arg>
        <bean class= "org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
    </constructor-arg>
    <property name="filterProcessesUrl" value="/logout/cas"/>
</bean>
<security:debug/>
<!-- General Configuration-->
<security:http
        auto-config="false"
        entry-point-ref="casEntryPoint">
    <security:intercept-url pattern="/" access="permitAll" />
    <security:intercept-url pattern="/login/cas" access="permitAll" />
    <!--<security:intercept-url pattern="/index.jsp" access="permitAll" />-->
    <security:intercept-url pattern="/view/app/pages/**" access= "hasRole('ROLE_ADMIN')" />
    <security:intercept-url pattern="/**" access= "hasRole('ROLE_USER')" />
    <security:custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER"/>
    <security:custom-filter ref="singleLogoutFilter" before="CAS_FILTER"/>
    <security:custom-filter ref="casFilter" position="CAS_FILTER" />
    <!--<security:csrf disabled="true"/>-->
    <security:custom-filter ref="csrfTokenFilter" after="CSRF_FILTER"/>
</security:http>

这里不再对配置进行逐条说明,CAS对应的配置不需要修改前后台代码,CSRF配置修改前后台代码参考《Spring Security实践(二):简单认证的实现》。在配置过程中需要注意以下几点:

  • serviceProperties中value的配置是web服务器的主机+/login/cas,该URL是service的值,会依据该值在CAS Server上生成ticket, 然后用来到WEB服务器上验证ticket。
  • casEntryPoint中的https://ssomanage.test.com:8443/cas/login是CAS Server用来输入用户凭证的入口,其中主机和端口配置成提供CAS Server服务的主机和端口即可。
  • 注意,因为WEB Server要和CAS Server建立HTTPS连接,所以必须将CAS Server的自签名证书或者一个可以用来验证CAS Server证书的CA证书导入WEB Server中,实验环境用的是Tomcat作为WEB Server,具体导入证书的步骤,参考《CAS单点登录数据库认证V1.0》文档。
  • requestSingleLogoutFilter用来指定登出操作的过滤器,其中https://ssomanage.test.com:8443/cas/logout是用来登出用户的,执行该操作之后,用户从CAS Server上登出,/logout/cas是用来登出应用的,在WEB Server上执行该操作之后,只会登出当前的WEB Server。
  • userService中配置的用户信息,主要用来做授权,绑定用户的角色。其中的用户密码不会用来验证用户。

演示

这里通过一个实际的例子来演示SSO登录的过程,并对其中的通信细节做简要说明。

操作示例

  • 登录WEB Server
  • 跳转到CAS Server进行认证
  • 认证成功后跳转到WEB Server

通信细节

  • 从WEB Server跳转到CAS Server
  • 携带用户名和密码到CAS上进行认证:
  • 认证通过之后跳转到WEB Server上获取认证信息:
  • 在WEB Server上认证通过之后,跳转到WEB资源页面:
  • 多应用登录的场景,此时A应用已经登录,再登录B:
  • 登出应用:
  • 登出CAS Server:

小结

本文说明了在Spring Security中应用CAS如何进行配置,并对操作和通信细节进行了演示。多个应用进行单点登录在实际环境中也经过测试,和单个应用登录并没有不同,在认证的时候携带了一个指定的ticket.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 主要介绍CAS SSO的认证流程。有关这方面的内容再网上也有很多资料,写这篇总结目的一来是自己在理解这块内容的时候...
    spilledyear阅读 9,868评论 1 17
  • 1. CAS 简介 1.1. What is CAS ? CAS ( Central Authenti...
    人在码途阅读 9,829评论 3 51
  • 【环境说明】:本文演示过程在同一个机器上的(也可以在三台实体机器或者三个的虚拟机上),环境如下: windows7...
    黄海佳阅读 8,832评论 2 15
  • 摘要: 第一节:单点登录简介 第一步:了解单点登录 SSO主要特点是: SSO应用之间使用Web协议(如HTTPS...
    ITsupuerlady阅读 787评论 0 4
  • 割下青草 装进你的双眼 抓一把阳光 装进你的鞋 抽出洗衣机内的清香 装进你的肺 在银河舀一把星星 装进你的口袋 你...
    豌豆会喷火阅读 95评论 2 2