这样配置完成的项目存在一点问题,
首先它没有注册用户的功能,其次它的用户密码是明文密码,我们一般希望它用密文保存用户密码,提高安全性.
为了达到这个目的我们必须改造我们的testWeb1业务和casweb统一登录的配置.
首先看testWeb1项目,
我们新增加了一个register.jsp和一个注册用的servlet:RegServlet,内容如下:
register.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
这是一个注册业务!
<form action="RegServletExp" method="post">
<table cellpadding="0" cellspacing="0" border="0" >
<tr>
<td >用户名:</td>
<td>
<input name="name" class="input_text3" size="18" value="" type="text" /><b>*</b>
</td>
</tr>
<tr>
<td >密码:</td>
<td>
<input name="password" type="password" /><b>*</b>
</td>
</tr>
<tr>
<td class="key">确认密码:</td>
<td>
<input name="password2" type="password" /><b>*</b>
</td>
</tr>
<tr>
<td class="key"></td>
<td>
<input name="submit1" size="18" type="submit" />
</td>
</tr>
</table>
</form>
</body>
</html>
RegServlet.java内容:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.MD5;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class RegServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
String username = request.getParameter("name");
String pass = request.getParameter("password");
MD5 classMD5=new MD5();
pass=classMD5.encode(pass);
try {
Class obj = Class.forName("oracle.jdbc.driver.OracleDriver");
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection connection = DriverManager.getConnection(
"jdbc:oracle:thin:@10.2.17.230:1521:orcl", "casweb",
"casweb");
String sql2 = "Insert INTO USERTABLE1 (username,psw) values ('"
+ username + "','" + pass + "') ";
PreparedStatement stmt = connection.prepareStatement(sql2);
stmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hello World</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>注册成功!" + username + "</h1>");
out.println("</body>");
out.println("</html>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
doGet(request, response);
}
}
RegServlet.java引用了MD5加密类和数据库类,所以要在项目中导入ojdbc14.jar
MD5加密类需要引用cas-server-core-3.5.2.jar
package org;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.jasig.cas.authentication.handler.PasswordEncoder;
public class MD5 implements PasswordEncoder {
@Override
public String encode(String arg0) {
MessageDigest digest = null;
if (digest == null) {
try {
digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException nsae) {
nsae.printStackTrace();
}
}
// Now, compute hash.
digest.update(arg0.getBytes());
byte[] bytes = digest.digest();
StringBuffer buf = new StringBuffer(bytes.length * 2);
for (int i = 0; i < bytes.length; i++) {
if (((int) bytes[i] & 0xff) < 0x10) {
buf.append("0");
}
buf.append(Long.toString((int) bytes[i] & 0xff, 16));
}
return buf.toString().toUpperCase();
}
}
这样生成的用户密码就是加密的保存了.
接下了要修改testWeb1的web.xml配置,原来的配置,无法完成注册功能,因为过滤器会阻挡所有的URL请求.注册请求实际上应该在登录之前就可以做了.
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>testWeb1</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>serverName</param-name>
<param-value>http://localhost:8180</param-value>
</context-param>
<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:8080/casweb/login</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:8080/casweb</param-value>
</init-param>
</filter>
<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 Authentication Filter</filter-name>
<url-pattern>/casFil/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/casFil/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/casFil/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>HelloWorldExample</servlet-name>
<servlet-class>HelloWorld</servlet-class>
</servlet>
<servlet>
<servlet-name>RegServlet</servlet-name>
<servlet-class>RegServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RegServlet</servlet-name>
<url-pattern>/RegServletExp</url-pattern>
</servlet-mapping >
<servlet-mapping>
<servlet-name>HelloWorldExample</servlet-name>
<url-pattern>/casFil/servlet/HelloWorldExample</url-pattern>
</servlet-mapping>
</web-app>
原来的页面功能移动到casFile文件夹下,这样还能保证访问的安全性.register.jsp放在根目录,这样cas的过滤器就不会对它起作用了.
由于数据库用密文保存秘密,casweb统一登录的配置也需要更改.
先把编译完成的加密类 MD5.class放置于正确的位置,路径如下:
D:\GreenProg\apache-tomcat-7.0.39\webapps\casweb\WEB-INF\classes\org\MD5.class
另外,修改deployerConfigContext.xml配置,使MD5加密校验生效,我去掉部分注释,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!--
| This bean declares our AuthenticationManager. The CentralAuthenticationService service bean
| declared in applicationContext.xml picks up this AuthenticationManager by reference to its id,
| "authenticationManager". Most deployers will be able to use the default AuthenticationManager
| implementation and so do not need to change the class of this bean. We include the whole
| AuthenticationManager here in the userConfigContext.xml so that you can see the things you will
| need to change in context.
+-->
<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:@10.2.17.230:1521:orcl</value></property>
<property name="username"><value>casweb</value></property>
<property name="password"><value>casweb</value></property>
</bean>
<!-- 自定义的用户密码编码class+-->
<bean id="myPasswordEncoder" class="org.MD5"/>
<bean id="authenticationManager"
class="org.jasig.cas.authentication.AuthenticationManagerImpl">
<property name="credentialsToPrincipalResolvers">
<list>
<!--
| UsernamePasswordCredentialsToPrincipalResolver supports the UsernamePasswordCredentials that we use for /login
| by default and produces SimplePrincipal instances conveying the username from the credentials.
|
| If you've changed your LoginFormAction to use credentials other than UsernamePasswordCredentials then you will also
| need to change this bean declaration (or add additional declarations) to declare a CredentialsToPrincipalResolver that supports the
| Credentials you are using.
+-->
<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" >
<property name="attributeRepository" ref="attributeRepository" />
</bean>
<!--
| HttpBasedServiceCredentialsToPrincipalResolver supports HttpBasedCredentials. It supports the CAS 2.0 approach of
| authenticating services by SSL callback, extracting the callback URL from the Credentials and representing it as a
| SimpleService identified by that callback URL.
|
| If you are representing services by something more or other than an HTTPS URL whereat they are able to
| receive a proxy callback, you will need to change this bean declaration (or add additional declarations).
+-->
<bean
class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" />
</list>
</property>
<!--
| Whereas CredentialsToPrincipalResolvers identify who it is some Credentials might authenticate,
| AuthenticationHandlers actually authenticate credentials. Here we declare the AuthenticationHandlers that
| authenticate the Principals that the CredentialsToPrincipalResolvers identified. CAS will try these handlers in turn
| until it finds one that both supports the Credentials presented and succeeds in authenticating.
+-->
<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.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" /-->
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<property name="sql" value="select PSW from USERTABLE1 where USERNAME=?" />
<property name="dataSource" ref="dataSource" />
<!-- 用户密码编码方式+-->
<property name="passwordEncoder" ref="myPasswordEncoder"/>
</bean>
</list>
</property>
</bean>
<sec:user-service id="userDetailsService">
<sec:user name="@@THIS SHOULD BE REPLACED@@" password="notused" authorities="ROLE_ADMIN" />
</sec:user-service>
<!--
Bean that defines the attributes that a service may return. This example uses the Stub/Mock version. A real implementation
may go against a database or LDAP server. The id should remain "attributeRepository" though.
-->
<bean id="attributeRepository"
class="org.jasig.services.persondir.support.StubPersonAttributeDao">
<property name="backingMap">
<map>
<entry key="uid" value="uid" />
<entry key="eduPersonAffiliation" value="eduPersonAffiliation" />
<entry key="groupMembership" value="groupMembership" />
</map>
</property>
</bean>
<!--
Sample, in-memory data store for the ServiceRegistry. A real implementation
would probably want to replace this with the JPA-backed ServiceRegistry DAO
The name of this bean should remain "serviceRegistryDao".
-->
<bean
id="serviceRegistryDao"
class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl">
<property name="registeredServices">
<list>
<bean class="org.jasig.cas.services.RegexRegisteredService">
<property name="id" value="0" />
<property name="name" value="HTTP and IMAP" />
<property name="description" value="Allows HTTP(S) and IMAP(S) protocols" />
<property name="serviceId" value="^(https?|imaps?)://.*" />
<property name="evaluationOrder" value="10000001" />
</bean>
</list>
</property>
</bean>
<bean id="auditTrailManager" class="com.github.inspektr.audit.support.Slf4jLoggingAuditTrailManager" />
<bean id="healthCheckMonitor" class="org.jasig.cas.monitor.HealthCheckMonitor">
<property name="monitors">
<list>
<bean class="org.jasig.cas.monitor.MemoryMonitor"
p:freeMemoryWarnThreshold="10" />
<!--
NOTE
The following ticket registries support SessionMonitor:
* DefaultTicketRegistry
* JpaTicketRegistry
Remove this monitor if you use an unsupported registry.
-->
<bean class="org.jasig.cas.monitor.SessionMonitor"
p:ticketRegistry-ref="ticketRegistry"
p:serviceTicketCountWarnThreshold="5000"
p:sessionCountWarnThreshold="100000" />
</list>
</property>
</bean>
</beans>
配置修改完成后,重启动Tomcat服务器,访问新的注册页面就可以增加新用户并且登录系统了!
注册页面如下:http://localhost:8180/testWeb1/register.jsp
访问其他页面验证注册成功
http://localhost:8180/testWeb1/casFil/NewFile.jsp
最后,我们察看一下数据库,确认密码保存方式是密文: