手记

《SSO CAS单点系列》之 实操!轻松玩转SSO CAS就这么简单(相知篇)

作者: 常明,Java架构师
[请尊重原创,盗版必究,转载请指明出处]


上一篇《相识篇》我们进行了登录登出流程定制和页面定制实践,本篇我们继续通过实践深入认识CAS。

记住密码也是我们登录常提供的功能,CAS本身已经提供。下面我们来看下如何配置来实现这个功能,我们还是继续使用前面的例子作为实践。

1. 修改deployerConfigContext.xml,找到bean id="authenticationManager" 定义区,里面添加如下内容:

<property name="authenticationMetaDataPopulators">
  <util:list>
    <bean class="org.jasig.cas.authentication.principal.RememberMeAuthenticationMetaDataPopulator" />
  </util:list>
</property>

此处的修改主要是将页面提交的rememberMe属性传递到内部生成的authentication对象中。

2. 修改登录流程文件内容,根据上篇实践工程,我们现在使用的是nebula-login-webflow.xml

修改credential为:

<var name="credential" class="org.jasig.cas.authentication.RememberMeUsernamePasswordCredential" />

viewLoginForm中增加rememberMe绑定变量:

<binder>
  <binding property="username" />
  <binding property="password" />
  <binding property="rememberMe" />
</binder>

此处主要是接收登录页面的rememberMe属性。

3.ticketExpirationPolicies.xml文件中,注释掉原grantingTicketExpirationPolicy,启用新的票据过期策略:

<bean id="grantingTicketExpirationPolicy" class="org.jasig.cas.ticket.support.RememberMeDelegatingExpirationPolicy">
 <property name="sessionExpirationPolicy">
   <bean class="org.jasig.cas.ticket.support.TimeoutExpirationPolicy">
     <constructor-arg index="0" value="7200000" />
   </bean>
 </property>
 <property name="rememberMeExpirationPolicy">
  <bean class="org.jasig.cas.ticket.support.TimeoutExpirationPolicy">
    <constructor-arg index="0" value="604800000" />
  </bean>
 </property>
</bean>

上述TGT票据过期策略定义的是如果前端页面提交时“remember me”选项没有选中,定义的是false,执行2小时用户没有操作应用TGT过期策略,如果选中了免登录,7天过期。当然,可以根据情况修改上面的数字,注意单位是毫秒。

这是remember me这个功能的核心。我们知道TGT代表的是全局会话,remember me意味着全局会话的有效期延长,上述就是定义TGT的过期策略。

4. 最后是修改登录页面,增加“记住我”remember me选项:

<div><input type="checkbox" name="rememberMe" id="rememberMe" checked="true" />记住我</div>

好了,做了如上修改,我们启动工程,直接在认证中心登录,显示的登录页面为:

登录成功后,我们关掉浏览器,再打开,输入www.cas.com,则显示

此时,记住密码功能生效。

remember me主要涉及的是TGT的有效期问题,这里我们再深入讨论一下。TGT的有效期控制采用策略模式实现。缺省是TicketGrantingTicketExpirationPolicy,即应用空闲超过2小时,TGT存在超过8小时即过期策略。CAS提供了几种Policy,一般都能满足我们的需求,当然我们也可以根据需要自己定义特殊的Policy策略。

TGT缺省采用虚拟机内存方式存储,其生命周期由Policy控制。同时ticket的时效是被动后验方式,在这种情况下,我们还需要一个清除器定期清除内存中过期的还未经过处理的ticket。这个清除器在ticketRegistry.xml中定义,叫ticketRegistryCleaner,定时任务采用spring集成的Quartz实现。

当我们采用第三方Cache工具如redis、memcached等能控制数据存储时效的其它存储策略实现时,这时ticketRegistryCleaner就不再需要了。但要注意,存储数据时的有效时长要大于等于policy定义的有效时效。

我们知道,TGT的ID在客户端TGC Cookie中,因此保持全局会话,不仅要服务端TGT这个票据对象存在,同时TGC这个Cookie也不能过期。在ticketGrantingTicketCookieGenerator.xml中,缺省情况下p:cookieMaxAge设置为-1,表示长期有效。这里不需要修改,我们只需要服务端用policy控制TGT的有效期就可以了。

CAS给出的缺省例子是将账户信息(用户名/密码)放在配置文件中,实际运行系统,账户信息通常是在数据库中保存。现在我们就配置一下如何对数据库中保存的账户进行认证。

1. 首先,在mysql数据库中建立一张账户表account,并添加一些账户例子。

注意,密码我们使用了MD5加密方式。

2. 在deployerConfigContext.xml文件中找到bean id="primaryAuthenticationHandler" 区并注释掉,替换成如下内容:

<bean id="primaryAuthenticationHandler" 
  class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">   
 <property name="dataSource" ref="dataSource" />   
 <property name="sql" value="select password from account where username=? " />  <property  name="passwordEncoder"  ref="passwordEncoder"/>
</bean>

也就是说,我们替换了认证插件,采用SQL语句访问数据库获取密码认证方式。QueryDatabaseAuthenticationHandler在cas-server-support-jdbc子工程中。

CAS提供了多种认证方式,除JDBC访问数据库外,还可以使用LDAP、x509、spnego等方式,这些都以子工程插件的方式提供。当然,我们同样可以开发自己需要的插件。

由于我们密码使用了MD5加密方式,我们引进了passwordEncoder,定义如下:

<bean id="passwordEncoder"      
    class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder" autowire="byName">          
  <constructor-arg value="MD5"/>   
  <property name="characterEncoding">   
    <value>UTF-8</value>   
  </property>
</bean>

然后我们定义数据源,这在spring工程中很常见:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">   
  <property name="driverClassName">   
    <value>com.mysql.jdbc.Driver</value>   
  </property>   
  <property name="url">   
    <value>jdbc:mysql://127.0.0.1:3306/jiweibu?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true</value>   
  </property>   
  <property name="username" value="root" />   
  <property name="password" value="123456" />   
  <property name="initialSize" value="10" />
  <property name="maxActive" value="500" />  
  <property name="maxWait" value="60000" />  
  <property name="validationQuery"><value>select 1</value></property>
</bean>

3. 在pom.xml中引入下面三个工程包,包括CAS JDBC认证插件、Mysql驱动还有dbcp连接池:

<dependency>
  <groupId>org.jasig.cas</groupId>
  <artifactId>cas-server-support-jdbc</artifactId>
  <version>${project.version}</version>
  <scope>compile</scope>
</dependency>
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.26</version>
</dependency>
<dependency>
  <groupId>commons-dbcp</groupId>
  <artifactId>commons-dbcp</artifactId>
  <version>1.4</version>
</dependency>

重新编译build,运行修改的CAS认证中心,使用数据库中的账号尝试登录。

至此,我们介绍了如何修改登录登出流程,如何修改CAS Server相关界面,如何实现记住密码免登录功能,以及如何访问数据库中账号去认证。通过这些实践活动,我们对CAS有了相当的理解,可以应对一般的应用场景了。

后面,我们将进一步深入CAS,解决在大型互联网应用中,基于CAS实现SSO需要关注的问题。



本文出自慕课网,转载请注明出处,侵权必究。
6人推荐
随时随地看视频
慕课网APP

热门评论

加入数据验证就报错http://img.mukewang.com/57fe380d0001f69908630193.jpg方便的话看下是怎么回事,谢谢啦


试过关闭浏览器后还不行,百度了一下。

如果改用http协议,则需要将warnCookieGenerator.xml文件warnCookieGenerator节点p:cookieSecure属性值设置为false。

记住密码功能,我试验了,应该还缺少一个步骤,不然设置的过期时间就不生效。在ticketGrantingTicketCookieGenerator.xml的bean中增加  p:rememberMeMaxAge="xxxxxxx" ,要注意的是这里的xxxxxxx为秒数。并且要注意和ticketExpirationPolicies.xml中设置的保持一致。

查看全部评论