-
Notifications
You must be signed in to change notification settings - Fork 57
CAS单点登录模块
Zhang Baofeng edited this page Jun 11, 2013
·
1 revision
使用CAS来做统一的用户管理,和用户登录、身份验证相关的操作全部跳转到CAS让它来完成。单点登录是为了子系统们在用户管理方面的无缝衔接。我在自己机器上让CAS Server和solr Server共用了一个tomcat,端口在9080。CAS Client包导入web项目,并在web.xml里进行必要的filter和配置。在验证方面,我的jsp会从跳转回的结果里获取session里的信息,查看是否有登录了的用户,以此借助cas打通jsp和mysql数据库里的内容。
在deployerConfigContext.xml里配置了我的验证方式,读取我指定的mysql里的某table,并做一次查询。
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<property name="dataSource" ref="dataSource"></property>
<property name="sql" value="select password from UserInfo where username=?"></property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
<property name="url"><value>jdbc:mysql://localhost:3307/academic</value></property>
<property name="username"><value>root</value></property>
<property name="password"><value></value></property>
</bean>
Server端的一些jsp的定制就不介绍了,我没有对其进行页面的改写定制。在这个xml里,我还定制了需要cas额外获取并写在session里的一些信息,
<bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
<constructor-arg index="0" ref="dataSource"/>
<constructor-arg index="1" value="select * from UserInfo where {0}"/>
<property name="queryAttributeMapping">
<map>
<entry key="username" value="username" />
</map>
</property>
<property name="resultAttributeMapping">
<map>
<entry key="username" value="username"/>
<entry key="name" value="name"/>
<entry key="email" value="email"/>
<entry key="weibo_url" value="weibo_url"/>
<entry key="github_url" value="github_url"/>
<entry key="interests" value="interests"/>
<entry key="homepage" value="homepage"/>
</map>
</property>
</bean>
这部分session内的信息会存在一个特点的位置,下面会说明在jsp里怎么读取获取这些内容。
配置信息都在web.xml下,
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>AcademicSearchEngine</display-name>
<welcome-file-list>
<welcome-file>about.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 用于单点退出,该过滤器用于实现单点登出功能,可选配置 -->
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
<!-- 该过滤器用于实现单点登出功能,可选配置。 -->
<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>http://localhost:8443/cas/login</param-value>
</init-param>
<init-param>
<!--这里的server是服务端的IP -->
<param-name>serverName</param-name>
<param-value>http://localhost: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>http://localhost:8443/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://localhost:8080</param-value>
</init-param>
<init-param>
<param-name>useSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>redirectAfterValidation</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!-- 该过滤器负责实现HttpServletRequest请求的包裹, 比如允许开发者通过HttpServletRequest 的 getRemoteUser()方法获得SSO登录用户的登录名,可选配置。 -->
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>
org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<!-- 该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。 比如AssertionHolder.getAssertion().getPrincipal().getName()。 -->
<filter>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<!-- 自动根据单点登录的结果设置本系统的用户信息 -->
<filter>
<display-name>AutoSetUserAdapterFilter</display-name>
<filter-name>AutoSetUserAdapterFilter</filter-name>
<filter-class>dcd.academic.cas.AutoSetUserAdapterFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/home.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/home.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/home.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<url-pattern>/home.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>AutoSetUserAdapterFilter</filter-name>
<url-pattern>/home.jsp</url-pattern>
</filter-mapping>
</web-app>
在这个配置里,要注意一些端口、域名之类的名称,不然会造成各种失败的。可以看到我的过滤对象都和home.jsp有关,这是用户个人主页,所以需要cas跳转和验证这一环节。在home.jsp里,我进行了session内cas存放数据的验证,
<%
Object object = request.getSession().getAttribute("_const_cas_assertion_");
Assertion assertion = (Assertion) object;
String loginName = "";
String name = "";
String email = "";
String weibo_url = "";
String github_url = "";
String interests = "";
String homepage = "";
if (object != null) {
loginName = assertion.getPrincipal().getName();
Map<String, Object> map = assertion.getPrincipal().getAttributes();
name = (String) map.get("name");
email = (String) map.get("email");
weibo_url = (String) map.get("weibo_url");
github_url = (String) map.get("github_url");
interests = (String) map.get("interests");
homepage = (String) map.get("homepage");
}
%>
通过获取session里“const_cas_assertion”这个属性的对象,最后在一个map里得到cas存放的信息,为jsp所用。
CAS做登出的时候,需要页面单独做一次session的清空,不然登出的跳转还未登出的效果。更多关于CAS介绍、原理性、入门使用的内容,可以参考CAS解决单点登录SSO,之前我也做了点总结。