cas改造
关键字:
sso域名:passport.xiw.com
登陆地址(spring web flow):http://www.xiw.com/site/login
登陆地址(直接):https://passport.xiw.com/login?locale=zh_CN
退出地址:https://passport.xiw.com/logout
一、涉及模块
svn地址:
cas-client-core |
http://svnxiw.xiw.com/Userend/passport/cas_client/cas-client-core |
cas-server-core |
http://svnxiw.xiw.com/Userend/passport/cas-server-3.5.2/cas-server-core |
cas-server-webapp |
http://svnxiw.xiw.com/Userend/passport/cas-server-3.5.2/cas-server-webapp |
cas-server-support-jdbc |
http://svnxiw.xiw.com/Userend/passport/cas-server-3.5.2/cas-server-support-jdbc |
二、CAS 服务端的处理逻辑
CAS 服务端总共对外定义了9 个接口,客户端通过访问这9 个接口与服务端交互,这9个接口为:
接口 |
说明 |
备注 |
/login |
认证接口 |
|
/logout |
退出接口,负责销毁认证cookie |
|
/captcha.htm(新增) |
验证码认证功能接口 |
captchaImageCreateController |
/registerAutoLogin(新增) |
注册自动登录跳转接口 |
registerAutoLoginController |
详细说明:
/login:
登录流程这部分要考虑到不同种类用户凭证的获取方案,以及客户应用传来的service 、gateway 、renew 参数的不同取值组合,CAS 为了实现流程的高度可配置性,采用了Spring Web Flow 技术。通过CAS 发布包里的login-webflow.xml 、cas-servlet.xml 、applicationContext.xml 这3 个文件,找出 了登录有关的所有组件。
注:
1 : InitialFlowSetupAction: 是流程的入口。用 request.getContextPath() 的值来设置 cookie 的 Path 值, Cookie 的 path 值是在配置文件里定义的,但这个 Action 负责将 request.getContextPath() 的值设置为 Cookie 的 path 值,这是在 cas 部署环境改变的情况下,灵活地设置 cookie path 的方式;把 cookie 的值以及 service 参数的值放入 requestContext 的 flowscope 里。
2 : GenerateServiceTicketAction 此 Action 负责根据 service 、 GTC cookie 值生成 ServiceTicket 对象, ServiceTicket 的 ID 就是返回给客户应用的 ticket 参数,如果成功创建 ServiceTicket ,则转发到 WarnAction ,如果创建失败,且 gateway 参数为 true ,则直接redirect 到客户应用, 否则则需要重新认证。
3 : viewLoginForm 这是登录页面, CAS 在此收集用户凭证。 CAS 提供的默认实现是 /WEB-INF/view/jsp/simple/ui/casLoginView.jsp 。
4 : bindAndValidate 对应 AuthenticationViaFormAction 的 doBind 方法,该方法负责搜集登录页面上用户录入的凭证信息(用户名、密码等),然后把这些信息封装到 CAS 内部的 Credentials 对象中。用户在 casLoginView.jsp 页面上点击提交后,会触发此方法。
5:submit 对应 AuthenticationViaFormAction ImageVaditeAuthenticationViaFormAction的 submit 方法 , 如果 doBind 方法成功执行完, 则触发 submit 方法,此方法负责调用centralAuthenticationService 的 grantServiceTicket 方法,完成认证工作,如果认证成功,则生成 TicketGrantingTicket 对象,放在缓存里, TicketGrantingTicket 的 ID 就是 TGC Cookie 的 value 值。
6 : warn CAS 提供了一个功能:用户在一个 web 应用中跳到另一个 web 应用时, CAS 可以跳转到一个提示页面,该页面提示用户要离开一个应用进入另一个应用,可以让用户自己选择。用户在登录页面 viewLoginForm 上选中了 id=”warn” 的复选框,才能开启这个功能。
WarnAction 就检查用户有没有开启这个功能,如果开启了,则转发到showWarnView, 如果没开启,则直接redirect 到客户应用。
7 :SendTicketGrantingTicketAction 此Action 负责为response 生成TGC Cookie ,cookie 的值就是 AuthenticationViaFormAction 的submit 方法生成的 TicketGrantingTicket 对象的 ID 。
8 : viewGenerateLoginSuccess CAS 的认证成功页面。
/logout: ( 对应实现类 org.jasig.cas.web.LogoutController )
处理逻辑:
1) removeCookie
2) 在服务端删除TicketGrantingTicket 对象(此对象封装了cookie 的value 值)
3 )redirect 到退出页面,有2 种选择:
if(LogoutController 的followServiceRedirects 属性为true 值,且url 里的service 参数非空){
redirect 到 sevice 参数标识的url
}
else{
redirect 到内置的casLogoutView (cas/WEB-INF/view/jsp/default/ui/casLogoutView.jsp ),如果url 里有url 参数,则此url 参数标识的链接会显示在casLogoutView 页面上。
}
/registerAutoLogin: ( 对应实现类 org.jasig.cas.web.RegisterAutoLoginController )
三、认证相关的概念及流程
概念
Credentials 用户提供的用于登录用的凭据信息,如用户名/ 密码、证书、IP 地址、Cookie 值等。比如 UsernamePasswordCredentials ,封装的是用户名和密码。CAS 进行认证的第一步,就是把从UI 或request 对象里取到的用户凭据封装成Credentials 对象,然后交给认证管理器去认证。
AuthenticationHandler 认证Handler, 每种AuthenticationHandler 只能处理一种
Credentials ,如AbstractUsernamePasswordAuthenticationHandler 只负责处
理 U sernamePasswordCredentials 。
Principal 封装用户标识,比如 SimplePrincipal, 只是封装了用户名。认证成功
后, credentialsToPrincipalResolvers 负责由Credentials 生成 Principal 对象。
CredentialsToPrincipalResolvers 负责由 Credentials 生成 Principal 对象,每
种 CredentialsToPrincipalResolvers 只处理 一种Credentials ,
比如 UsernamePasswordCredentialsToPrincipalResolver 负责
从 U sernamePasswordCredentials 中取出用户名,然后将其赋给生成
的 SimplePrincipal 的 ID 属性。
AuthenticationMetaDataPopulators 负责将 Credentials 的一些属性赋值
给 Authentication 的 attributes 属性。
Authentication Authentication是认证管理器的最终处理结果, Authentication 封装
了 Principal ,认证时间,及其他一些属性(可能来自 Credentials )。
AuthenticationManager 认证管理器得到 Credentials 对象后,负责调度
AuthenticationHandler 去完成认证工作,最后返回的结果是 Authentication 对象。
CentralAuthenticationService CAS 的服务类,对 Web 层提供了一些方法。该类还负责调用 AuthenticationManager 完成认证逻辑。
login-webflow.xml
<!-- 验证码服务 simon 2013-10-26 修改这个 -->
<view-state id="viewLoginForm" view="loginxiw" model="credentials">
<binder>
<binding property="username"/>
<binding property="password"/>
<binding property="code"/>
</binder>
<on-entry>
<set name="viewScope.commandName" value="‘credentials‘"/>
</on-entry>
<transition to="realSubmit" on="submit" validate="true" bind="true">
<evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credentials)"/>
</transition>
</view-state>
<!-- 验证码服务 simon 2013-10-26 替换这个 -->
<var name="credentials" class="org.jasig.cas.authentication.principal.CaptchaImageLoginCredentials" />
deployerConfigContext.xml
<!--修改数据库验证 simon 2013-10-26-->
<bean class="org.jasig.cas.adaptors.jdbc.PassportxiwQueryDatabaseAuthenticationHandler">
<property name="dataSource" ref="springDataSource"/>
<property name="sql"
value="select password from UserLogin where lower(userName) = lower(?) and isLock=0" />
<property name="passwordEncoder" ref="md5PasswordEncoder" />
<property name="updateSql" value="update UserLogin set lastLoginIP=?,lastLoginTime=? where lower(userName) = lower(?)" />
</bean>
<!-- 修改数据库验证 simon 2013-10-26-->
<bean id="springDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://dbip/wxiw"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<bean id="myPasswordEncoder"
class="org.jasig.cas.authentication.handler.PlainTextPasswordEncoder" />
<bean id="md5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
<constructor-arg index="0" value="MD5" />
</bean>
<bean
class="org.jasig.cas.authentication.principal.CaptchaImageLoginCredentialsToPrincipalResolver">
<property name="attributeRepository" ref="attributeRepository" />
</bean>
Web.xml
<!-- 验证码服务 simon 2013-10-26 validate code-->
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/captcha.htm</url-pattern>
</servlet-mapping>
<!-- 注册自动登录 xiw 2014/7/23-->
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/registerAutoLogin</url-pattern>
</servlet-mapping>
来源: <https://tower.im/projects/76c15260e1e84919bee3f18c2e41f1b6/docs/0816f172fcfb4b9ab259aaf7fc164024/>