?Java综合Keytool使用举例:
命令:keytool -genkey -alias tomcat -keyalg RSA -keystore d:\mykeystore?
-dname "CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN"?
-keypass changeit -storepass -validity 180
参数说明:?
-genkey表示要创建一个新的密钥?
-dname表示密钥的Distinguished Names,?
CN=commonName (域名:建议使用配置的域名,也可使用localhost)
OU=organizationUnit?
O=organizationName?
L=localityName?
S=stateName?
C=country?
Distinguished Names表明了密钥的发行者身份?
-keyalg使用加密的算法,这里是RSA?
-alias密钥的别名?
-keypass私有密钥的密码,这里设置为changeit
-keystore 密钥保存在D:盘目录下的mykeystore文件中?
-storepass 存取密码,这里设置为changeit,这个密码提供系统从mykeystore文件中将信息取出?
-validity该密钥的有效期为 180天 (默认为90天)
?
2.导出证书
命令:D:\keys>keytool -export -file d:/keys/wsria.crt -alias wsria -keystore d:/keys/wsriakey
输入密码为上面生成证书时输入的密码(keystore)
?
3.为客户端的JVM导入证书
命令:keytool -import -keystore "%JAVA_HOME%/jre/lib/security/cacerts"?
-file D:/keys/wsria.crt -alias wsria
导入证书时出现java.io.IOException: Keystore was tampered with, or password was incorrect?
异常的解决办法:
输入保护密码,默认的就是changeit。
?
4.应用证书到Web服务器-Tomcat
启用Web服务器(Tomcat)的SSL,也就是HTTPS加密协议,
打开tomcat目录的conf/server.xml文件,开启83和87行的注释代码,
并设置keystoreFile、keystorePass修改结果如下:
Xml代码??- <Connector?port="8443"?protocol="HTTP/1.1"?SSLEnabled="true"??
- ???????????????maxThreads="150"?scheme="https"?secure="true"??
- ???????????????clientAuth="false"?sslProtocol="TLS"???
- ???????????????keystoreFile="D:/keys/wsriakey"??
- ??????????????keystorePass="keystore"??
- />??
?
参数说明:
keystoreFile:在第一步创建的key存放位置.?
keystorePass:创建证书时的密码.
Tomcat的SSL启用完成后,输入地址:https://sso.wsria.com:8443/访问。
?
三.?部署CAS服务器
1.CAS服务端下载:http://www.jasig.org/cas/download
2.下载完成后将cas-server-3.4.3.1.zip解压,
?解压cas-server-3.4.3/modules/cas-server-webapp-3.4.3.1.war,改名为cas,
?然后复制cas目录到你的tomcat/webapp目录下.
3.现在可以访问CAS应用了,当然要使用HTTPS加密协议访问,
https://sso.wsria.com:8443/cas/login,打开了CAS服务器的页面输入admin/admin点击登录。
?
4.?后台数据库身份验证
以上只是简单的身份验证,下面介绍CAS服务器如何配置数据库信息进行身份验证。
(1)首先打开tomcat/webapp/cas/WEB-INF/deployerConfigContext.xml文件,配置的地方如下:
注释掉:SimpleTestUsernamePasswordAuthenticationHandler这个验证Handler类,配置如下代码:
Xml代码?? - <bean?class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">??
- ?<property?name="dataSource"?ref="dataSource"?/>??
- ?<property?name="sql"?value="select?password?from?t_admin_user?where?login_name=?"/>??
- ?<property?name="passwordEncoder"?ref="MD5PasswordEncoder"/>??
- </bean>??
?
在文件的末尾之前加入如下代码:
Xml代码?? - <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:///wsriademo</value></property>??
- ???<property?name="username"><value>root</value></property>??
- ???<property?name="password"><value>root</value></property>??
- </bean>???
- <bean?id="MD5PasswordEncoder"???
- ???class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">????
- ??<constructor-arg?index="0">??
- ???<value>MD5</value>??
- ??</constructor-arg>??
- </bean>??
?
?
(2)复制cas-server-3.4.3.1\modules\cas-server-support-jdbc-3.4.3.1.jar
?? 和mysql驱动jar包到tomcat/webapp/cas/WEB-INF/lib目录。
?
配置解释:?
sql语句就是查询哪一张表,本例根据t_admin_user表的login_name字段查询密码,
CAS会匹配用户输入的密码,如果匹配则通过;下面是t_admin_user的表结构:?
? CREATE TABLE t_admin_user (
?? ?id BIGINT NOT NULL AUTO_INCREMENT,
??? email VARCHAR(255),
?? ?login_name VARCHAR(255) NOT NULL UNIQUE,
?? ?name VARCHAR(255),
?? ?password VARCHAR(255),
?? ?PRIMARY KEY (id)
??? ) ENGINE=InnoDB;
passwordEncoder:处理密码的加密,根据数据库保存的是明码还是加密过的进行选择配置。
cas内置了MD5的 功能所以只需要配置一下就可以了.实际应用中可使用自定义的加密算法,
实现方式也比较简单,创建 一个类继承org.jasig.cas.authentication.handler.PasswordEncoder,
然后在encode方法中加密用户输入的密码然后返回即可。
四.?配置CAS客户端
1. 下载cas-client,地址:http://www.ja-sig.org/downloads/cas-clients/,
?? 在modules文件夹中有需要的jar包,将cas-client-core-3.2.1.jar包拷贝到客户端应用中。
?或使用以下maven配置:
Xml代码?? - <dependency>??
- ?<groupId>org.jasig.cas.client</groupId>??
- ?<artifactId>cas-client-core</artifactId>??
- ?<version>3.1.12</version>??
- </dependency>??
?
2.在web.xml文件中进行如下配置:
Xml代码?? - <!--?用于单点退出,该过滤器用于实现单点登出功能,可选配置-->??????
- <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://localhost:8443/cas/login??
- ????????</param-value>??
- ????????<!--这里的server是服务端的IP-->??
- ????</init-param>??
- ????<init-param>??
- ????????<param-name>serverName</param-name>??
- ????????<param-value>http://localhost:8080</param-value>??
- ????</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://localhost:8443/cas</param-value>??
- ????</init-param>??
- ????<init-param>??
- ????????<param-name>serverName</param-name>??
- ????????<param-value>http://localhost:8080</param-value>??
- ????</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>??
- <!--?自动根据单点登录的结果设置本系统的用户信息?-->??
- <filter>??
- ????<display-name>AutoSetUserAdapterFilter</display-name>??
- ????<filter-name>AutoSetUserAdapterFilter</filter-name>??
- ????<filter-class>??
- ????????com.cas.client.filter.AutoSetUserAdapterFilter??
- ????</filter-class>??
- </filter>??
- <filter-mapping>??
- ????<filter-name>AutoSetUserAdapterFilter</filter-name>??
- ????<url-pattern>/*</url-pattern>??
- </filter-mapping>??
?
需注意二点:
?? (1)服务端拦截地址:https://localhost:8443/cas/,如果证书中指定的域名为sso.wsria.com,
?????? 则为https://sso.wsria.com:8443/cas/,本事例的域名地址指定为localhost。
?? (2)客户端应用地址:http://localhost:8080,该地址为客户端应用访问的地址。
????? 过滤器认证和Ticket认证类似。
?
3.AutoSetUserAdapterFilter类设置登录用户session信息代码如下:
Java代码?? - public?class?AutoSetUserAdapterFilter?implements?Filter{??
- ????public?void?destroy()?{??
- ????}??
- ????/**?
- ?????*?过滤逻辑:首先判断单点登录的账户是否已经存在本系统中,?????????
- ?????*?如果不存在使用用户查询接口查询出用户对象并设置在Session中????
- ?????*/??
- ????public?void?doFilter(ServletRequest?request,?ServletResponse?response,??
- ????????????FilterChain?chain)?throws?IOException,?ServletException?{??
- ???????????HttpServletRequest?httpRequest?=?(HttpServletRequest)?request;?????
- ???????????//?_const_cas_assertion_是CAS中存放登录用户名的session标志?????????????
- ??????????Object?object?=?httpRequest.getSession().getAttribute("_const_cas_assertion_");????
- ??????????if?(object?!=?null)?{???????????????????????
- ??????????????Assertion?assertion?=?(Assertion)?object;?????
- ??????????????String?loginName?=?assertion.getPrincipal().getName();?????
- ??????????????System.out.println("登录名为:"+loginName);??
- ??????????????//?接下来在本业务系统中根据用户名获取用户对象,判断session中是否存在,??
- ??????????????//?如果不存在,则获取用户对象保存到session中,否则直接获取用户对象。???????????????
- ??????????}???
- ??????????chain.doFilter(request,?response);???
- ????}??
- ????public?void?init(FilterConfig?filterConfig)?throws?ServletException?{??
- ????}??
- }??
?五.?美化CAS服务器界面
可定制开发自己CAS服务端页面,复制 cas\WEB-INF\view\jsp\default\ui的一些JSP文件,进行修改替换就行了。
例如:
? 登录界面:casLoginView.jsp
? 登录成功:casGenericSuccess.jsp
? 登出界面:casLogoutView.jsp