http://blog.csdn.net/yunye114105/article/details/7997041
参考:
http://blog.csdn.net/diyagea/article/details/50638737
(配置SSL协议)http://www.cnblogs.com/notDog/p/5264666.html
背景
有几个相对独立的java的web应用系统, 各自有本身的登录验证功能,用户在使用不一样的系统的时候,须要登录不一样的系统。如今须要提供一个统一的登录/登出界面, 而不修改各个系统原来的登录验证机制。因而采用单点登陆系统CAS。
使用步骤
要使用单点登陆,须要部署CAS系统, CAS服务端能够直接部署在tomcat下运行, 对于CAS服务端来讲,全部要集成单点登陆的web应用都是它的一个客户端, CAS有客户端jar包, 客户端web应用须要引入CAS客户端的jar包,这样CAS系统的服务端和客户端web应用程序端才能通讯。
客户端web应用程序的经过配置web.xml,添加CAS须要的各类过滤器,来实现和CAS服务器通讯, 用户信息验证工做在CAS服务端统一完成, 验证经过后,客户端web应用程序只须要补全本身的Session信息便可。
各个客户端web应用程序须要使用一个公用的用户表。
第一步 部署CAS系统服务端
1.从官网http://developer.jasig.org/cas/下载CAS Server, 将cas-server-webapp-3.4.12.war解压, 能够看到是一个标准的java的web应用, 能够直接部署到tomcat的webapps目录下的,我这里假设部署的路径是{tomcat_home}/webapps/cas。
2. CAS默认须要tomcat配置SSL协议,使用https协议通讯的。 因为项目是企事业单位内部的系统,不须要这么高的安全级别, 能够简化操做,不走SSL协议。修改下配置文件\WEB-INF\spring-configuration\ticketGrantingTicketCookieGenerator.xml, 以下, 将默认的true改为false便可。
- <bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
- p:cookieSecure="false"
- p:cookieMaxAge="-1"
- p:cookieName="CASTGC"
- p:cookiePath="/cas" />
3.配置登陆的验证逻辑, 修改配置文件cas\WEB-INF\deployerConfigContext.xml。在authenticationHandlers中配置验证方式,我这里配置数据库查询语句来实现用户名和密码的验证。
- <property name="authenticationHandlers">
- <list>
- <!--
- | This is the authentication handler that authenticates services by means of callback via SSL, thereby validating
- | a server side SSL certificate.
- +-->
- <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
- p:httpClient-ref="httpClient" />
- <!--
- | This is the authentication handler declaration that every CAS deployer will need to change before deploying CAS
- | into production. The default SimpleTestUsernamePasswordAuthenticationHandler authenticates UsernamePasswordCredentials
- | where the username equals the password. You will need to replace this with an AuthenticationHandler that implements your
- | local authentication strategy. You might accomplish this by coding a new such handler and declaring
- | edu.someschool.its.cas.MySpecialHandler here, or you might use one of the handlers provided in the adaptors modules.
- +-->
- <bean class="org.jasig.cas.adaptors.jdbc.SearchModeSearchDatabaseAuthenticationHandler">
<property name="dataSource" ref="ds"/>
<property name="tableUsers" value="user"/>
<property name="fieldUser" value="username"/>
<property name="fieldPassword" value="password"/>
</bean>
- <!-- <bean
- class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" /> -->
- <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
- <property name="sql" value="select password from userTable where userName=?" />
- <property name="passwordEncoder" ref="passwordEncoder"/>
- <property name="dataSource" ref="dataSource" />
- </bean> -->
- </list>
- </property>
密码加密方法我这里使用MD5, 配置passwordEncoder的bean
- <bean id="passwordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder" autowire="byName">
- <constructor-arg value="MD5"/>
- </bean>
在配置一个名称为dataSource的数据源
- <bean id="dataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource">
- <property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"></property>
- <property name="driverUrl" value="jdbc:sqlserver://localhost:1433;databaseName=testDB;"></property>
- <property name="user" value="sa"></property>
- <property name="password" value="123456"></property>
- <property name="maximumConnectionCount" value="100"></property>
- <property name="minimumConnectionCount" value="1"></property>
- </bean>
数据源的配置根据本身的实际状况来配置, 须要的jar若是lib下面没有,本身复制进去, 否则数据源连不上报错。
4. 如今服务端就配置好了, 若是须要定制登陆/登出页面的话(实际项目基本上都须要修改), 修改cas\WEB-INF\view\jsp\default\ui\下面的casLoginView.jsp和casLogoutView.jsp就能够了
第二步 客户端web应用程序集成CAS
2 .配置web.xml文件, 主要是添加过滤器拦截通讯, 下面的实例代码, 假设web应用程序的端口是8080
4. 注意上步配置文件中,过滤器CasForInvokeContextFilter的实现是须要在具体的应用中实现的,他的目的是, CAS服务端登陆验证成功后,会将登陆用户的用户名携带回来, 这时客户端web应用程序须要根据用户名从数据库用户表中查询到用户的Id等信息, 并填充到Session中, 这样,客户端应用程序原来的验证逻辑就不会出问题了, 由于咱们通常都是经过验证session中是否含有当前登陆的用户的ID来进行登陆验证的。
下面是CasForInvokeContextFilter的一个简单实现。
- public class CasForInvokeContextFilter implements Filter {
-
- @Override
- public void destroy() {
- }
-
- @Override
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
- HttpSession session = ((HttpServletRequest) request).getSession();
-
- if (session.getAttribute("j_userId") == null) {
-
- Assertion assertion = AssertionHolder.getAssertion();
- String userName = assertion.getPrincipal().getName();
-
- try {
-
- User user = UserDao.getUserByName(userName);
- session.setAttribute("username", userName);
- session.setAttribute("userId", user.getId());
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- chain.doFilter(request, response);
- }
-
- @Override
- public void init(FilterConfig config) throws ServletException {
- }
- }
到此,就完成了, 当你访问具体应用的网址, 如http://具体应用IP: 8080/ ,就会跳转到CAS服务器的登录页面: http://CAS服务器IP: 8080/ 进行登陆验证, 验证经过后, 又会跳转回应用的网址。
第三步 单点登出
这个比较简单, 只要在系统的登出事件中, 将URL访问地址指向CAS服务登出的servlet, 就能够了。
http://CAS服务器IP:8080/cas/logout