生成证书前需要配置证书:
1、生成证书
用JDK自带的keytool工具生成证书:
D盘下创建keys文件,不需要创建hailong
命令:keytool -genkey -alias(别名)hailong -keyalg RSA -keystore D:/keys/hailong
hailong 是证书别名
2、导出证书
命令:C:\>keytool -export -file d:/keys/hailongCRT.crt -alias hailong(别名要一致) -keystore d:/keys/hailong
.crt密钥文件
3、把证书导入到客户端JDK中。
命令:keytool -import -keystore D:\software\jdk\java1.7\jdk1.7.0_79\jre\lib\security\cacerts -file D:/keys/hailongCRT.crt -alias hailong
如果出现以下错误,把...jdk1.7.0_79\jre\lib\security下的cacerts文件删除掉,在执行。
eytool错误: java.io.IOException: Keystore was tampered with, or password was incorrect
4、配置服务端
下载CAS的服务端,解压,把解压后的文件中文件夹中的cas-server-webapp-3.4.8.war文件拷贝的apache-tomcat-7.0.73\webapps下,并修改文件名为:cas.war。
2、修改apache-tomcat-7.0.73\conf\server.xml文件,去掉此文件83到93行之间的注释,修改为:
5、启动tomcat
账号 admin,密码 admin 默认账号和密码一样就行
配置host域名,用https访问 https://sso.wsria.com:8443/cas
具体链接 http://www.kafeitu.me/sso/2010/11/05/sso-cas-full-course.html
http://liujiawinds.iteye.com/blog/1990715
cas客户端配置
<!-- pom.xml-->
<dependency> <groupId>org.jasig.cas.client</groupId> <artifactId>cas-client-core</artifactId> <version>3.1.12</version> </dependency>
<!-- ======================== 单点登录开始 ======================== --> <!-- 用于单点退出,该过滤器用于实现单点登出功能,可选配置 --> <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-mapping> <filter-name>CAS Single Sign Out Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 该过滤器负责用户的认证工作,必须启用它 --> <filter> <filter-name>CASFilter</filter-name> <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class> <init-param> <param-name>casServerLoginUrl</param-name> <param-value>https://www.hailongsso.com:8443/cas/login</param-value> <!--这里的server是服务端的IP,点单登录地址链接 --> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://www.hailongsso.com:8081</param-value><span style="color:#FF0000;"> ①</span> <!--登录后的客户链接地址 --> </init-param> </filter> <filter-mapping> <filter-name>CASFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 该过滤器负责对Ticket的校验工作,必须启用它 --> <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>https://www.hailongsso.com:8443/cas</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://www.hailongsso.com:8081</param-value> <span style="color:#FF0000;">②</span> </init-param> </filter> <filter-mapping> <filter-name>CAS Validation Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 该过滤器负责实现HttpServletRequest请求的包裹, 比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。 --> <filter> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <filter-class> org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class> </filter> <filter-mapping> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 该过滤器使得开发者可以通过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-mapping> <filter-name>CAS Assertion Thread Local Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- ======================== 单点登录结束 ======================== -->
输入客户端地址 http://www.hailongsso.com:8081/SingleSignOnExample
重定向到cas单点登录画面
拦截认证的AuthenticationFilter.java具体分析
public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException { final HttpServletRequest request = (HttpServletRequest) servletRequest; final HttpServletResponse response = (HttpServletResponse) servletResponse; //TGC Cookie传过来了,验证一下是不是其生成的,如果是,那我用TGT签发一个ST,redirect给浏览器 //session 对应 TGC Cookie 三次进入 null 有值 有值 // 第一次来,没有TGC Cookie,客户端输入账号密码后去cas才能有 final HttpSession session = request.getSession(false); //assertion 对应ST 三次进入 null null 有值 // 第二次来,没有ST,第三次进来去CAS申请后才有值。 final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null; if (assertion != null) { filterChain.doFilter(request, response); return; } final String serviceUrl = constructServiceUrl(request, response); final String ticket = CommonUtils.safeGetParameter(request,getArtifactParameterName()); final boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl); if (CommonUtils.isNotBlank(ticket) || wasGatewayed) { filterChain.doFilter(request, response); return; } final String modifiedServiceUrl; log.debug("no ticket and no assertion found"); if (this.gateway) { log.debug("setting gateway attribute in session"); modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl); } else { modifiedServiceUrl = serviceUrl; } if (log.isDebugEnabled()) { log.debug("Constructed service url: " + modifiedServiceUrl); } final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway); if (log.isDebugEnabled()) { log.debug("redirecting to \"" + urlToRedirectTo + "\""); } response.sendRedirect(urlToRedirectTo); }
对于cas客户端的认证和拦截配置到具体的业务服务项目里,对认证拦截可以有自定义的规则,重写或替换AuthenticationFilter.java等类。
修改CAS的认证逻辑
CAS默认的逻辑是用户名和密码一致就可以登陆,现在需要把原web系统的用户名和密码校验挪到CAS中。这里假设原先web系统中有一张sys_user表存储了用户名和MD5散列后的密码。
打开cas/WEB-INF/deployerConfigContext.xml
注释掉SimpleTestUsernamePasswordAuthenticationHandler这个Handler,并添加
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"> <property ref="dataSource" name="dataSource"></property> <property name="sql" value="select t.encrypted_user_password from sys_user t where t.user_name=?"></property> <property ref="MD5PasswordEncoder" name="passwordEncoder"></property> </bean>
在文件末尾之前加入数据库的链接:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"> <value>oracle.jdbc.driver.OracleDriver</value> </property> <property name="url"> <value>jdbc:oracle:thin:@yourIP:1521:yourOracleInstanceId</value> </property> <property name="username"> <value>yourName</value> </property> <property name="password"> <value>yourPassword</value> </property> </bean> <bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"> <constructor-arg index="0"> <value>MD5</value> </constructor-arg> </bean>
cas加入jdbc支持
复制cas-server-3.5.2\modules\cas-server-support-jdbc-3.5.2.jar和oracle驱动(这里采用oracle数据)的ojdbc14.jar或者classes12.jar放到cas/WEB-INF/lib目录下。
cas-server-webapp源码打包cas-server-webapp.war修改成cas.war
就是以上所说服务的war包: