一、web.xml中配置过滤器。能过滤需要拦截的访问。
<!-- 自动登录过滤器 -->
<filter>
<filter-name>autoLogonFilter</filter-name>
<filter-class>
com.whaty.platform.filter.AutoLogonFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>autoLogonFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
二、cookie工具类的编写。
public
class
CookieUtil {
//保存cookie时的cookieName
private final static String cookieDomainName = "com.whaty" ;
//加密cookie时的网站自定码
private final static String webKey = "whaty" ;
//设置cookie有效期是两个星期,根据需要自定义
private final static long cookieMaxAge = 60 * 60 * 24 * 7 * 2;
//保存Cookie到客户端----------
//在CheckLogonServlet.java中被调用
//传递进来的user对象中封装了在登陆时填写的用户名与密码
publicstatic void saveCookie(SsoUser user, HttpServletResponse response) {
//cookie的有效期long validTime = System.currentTimeMillis() + (cookieMaxAge * 1000);//MD5加密用户详细信息String cookieValueWithMd5 =getMD5(user.getLoginId() +":" + user.getPassword()+ ":" + validTime + ":" + webKey);//将要被保存的完整的Cookie值String cookieValue = user.getLoginId() +":" + validTime + ":" + cookieValueWithMd5;//再一次对Cookie的值进行BASE64编码String cookieValueBase64 =new String(Base64.encode(cookieValue.getBytes()));//开始保存CookieCookie cookie =new Cookie(cookieDomainName, cookieValueBase64);//存两年(这个值应该大于或等于validTime)cookie.setMaxAge(60 * 60 * 24 * 365 * 2);//cookie有效路径是网站根目录cookie.setPath("/");//向客户端写入response.addCookie(cookie);
}//用户注销时,清除Cookie,在需要时可随时调用publicstatic void clearCookie( HttpServletResponse response){
Cookie cookie =new Cookie(cookieDomainName,null);cookie.setMaxAge(0);cookie.setPath("/");response.addCookie(cookie);
}//获取Cookie组合字符串的MD5码的字符串publicstatic String getMD5(String value) {
String result =null;try{
byte[] valueByte = value.getBytes();MessageDigest md = MessageDigest.getInstance("MD5");md.update(valueByte);result =toHex(md.digest());
} catch (NoSuchAlgorithmException e2){e2.printStackTrace();}
return result;}//将传递进来的字节数组转换成十六进制的字符串形式并返回privatestatic String toHex(byte[] buffer){
StringBuffer sb =new StringBuffer(buffer.length * 2);for (int i = 0; i < buffer.length; i++){
sb.append(Character.forDigit((buffer[i] & 0xf0) >> 4, 16));sb.append(Character.forDigit(buffer[i] & 0x0f, 16));
}}return sb.toString();}
三、登录的控制。
登录验证通过后,判断是否勾选了自动登录,如果选择就往客户端写cookie。
private boolean auto;public boolean isAuto() { //boolean的getter()方法是isAuto()
return auto;
}public void setAuto(boolean auto) {
this.auto = auto;
}if (auto) {
CookieUtil.saveCookie(ssoUser, response);
} else {
CookieUtil.clearCookie(response);
}
页面写法:
<inputtype="checkbox"name="auto"id="auto"checked="checked"/>两周自动登录
四、过滤器的编写。
ApplicationContextcontext = MyApplicationContextUtil.getContext();SsoUserServicessoUserService = (SsoUserService) context.getBean("ssoUserService");// 保存cookie时的cookieNameprivatefinal static String cookieDomainName ="com.whaty";// 加密cookie时的网站自定码privatefinal static String webKey ="whaty";@Overridepublicvoid destroy() {}@Overridepublicvoid doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)throws IOException,ServletException {
HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) resp;HttpSession session = request.getSession(true);SsoUser user = (SsoUser) session.getAttribute("user");String path = request.getRequestURI().substring(request.getContextPath().length());if ("/sso/authimg".equals(path)) {
// 以上操作及网页不过滤chain.doFilter(request, response);return;
}// 如果封装的user不为空,说明已经登陆,则继续执行用户的请求.下面的就不处理了if (user !=null) {
chain.doFilter(request, response);return;
}// 如果是执行退出后的跳转就跳到首页,而不进行处理。String isOut = (String) session.getAttribute("exit");if ("exit".equals(isOut) &&"/".equals(path)) {
session.removeAttribute("exit");chain.doFilter(request, response);return;
}// user为空,说明用户还没有登陆,就尝试得到浏览器传送过来的CookieCookie cookies[] = request.getCookies();String cookieValue =null;if (cookies !=null) {
for (int i = 0; i < cookies.length; i++) {
if (cookieDomainName.equals(cookies[i].getName())) {
cookieValue = cookies[i].getValue();break;
}
}
}// 如果cookieValue为空,也继续执行用户请求if (cookieValue ==null) {
chain.doFilter(request, response);return;
}// cookieValue不为空执行下面的方法,调用CookieUtil.java中的readCookieAndLogon方法try {
this.readCookieAndLogon(request, response, chain);
} catch (Exception e) {
e.printStackTrace();
}
}@Overridepublicvoid init(FilterConfig filterConfig)throws ServletException {}// 读取Cookie,自动完成登陆操作--------------------------------// 在Filter程序中调用该方法,见AutoLogonFilter.javapublicvoid readCookieAndLogon(HttpServletRequest request, HttpServletResponse response, FilterChain chain)throws IOException, ServletException, UnsupportedEncodingException {
// 根据cookieName取cookieValueCookie cookies[] = request.getCookies();String cookieValue =null;if (cookies !=null) {
for (int i = 0; i < cookies.length; i++) {
if (cookieDomainName.equals(cookies[i].getName())) {cookieValue = cookies[i].getValue();break;}
}
}// 如果cookieValue为空,返回,if (cookieValue ==null) {
return;
}// 如果cookieValue不为空,才执行下面的代码// 先得到的CookieValue进行Base64解码String cookieValueAfterDecode =new String(Base64.decode(cookieValue),"utf-8");// 对解码后的值进行分拆,得到一个数组,如果数组长度不为3,就是非法登陆String cookieValues[] = cookieValueAfterDecode.split(":");if (cookieValues.length != 3) {
response.setContentType("text/html;charset=utf-8");PrintWriter out = response.getWriter();out.println("你正在用非正常方式进入本站...");out.close();return;
}// 判断是否在有效期内,过期就删除Cookielong validTimeInCookie =new Long(cookieValues[1]);if (validTimeInCookie < System.currentTimeMillis()) {
// 删除CookieCookieUtil.clearCookie(response);response.setContentType("text/html;charset=utf-8");PrintWriter out = response.getWriter();out.println("<a href=’logon.jsp’>你的Cookie已经失效,请重新登陆</a>");out.close();return;
}// 取出cookie中的用户名,并到数据库中检查这个用户名,String loginId = cookieValues[0];// 根据用户名到数据库中检查用户是否存在SsoUser user =null;try {
if (loginId !=null) {
user =ssoUserService.getByLoginId(loginId.toLowerCase());
}
} catch (EntityException e) {
e.printStackTrace();
}// 如果user返回不为空,就取出密码,使用用户名+密码+有效时间+ webSiteKey进行MD5加密if (user !=null) {
String md5ValueInCookie = cookieValues[2];String md5ValueFromUser = CookieUtil.getMD5(user.getLoginId() +":" + user.getPassword() + ":"+ validTimeInCookie +":" + webKey);// 将结果与Cookie中的MD5码相比较,如果相同,写入Session,自动登陆成功,并继续用户请求if (md5ValueFromUser.equals(md5ValueInCookie)) {
try {
//这里写登录成功后的属性设置。this.setInit(user, request);
} catch (RuntimeException e) {
e.printStackTrace();return;
}
response.sendRedirect("/entity/teacher/pe_assess_index.jsp");
}
} else {
// 返回为空执行response.setContentType("text/html;charset=utf-8");PrintWriter out = response.getWriter();out.println("cookie验证错误!");out.close();return;
}}
}
五、这样在退出出的方法中清session 的时候也清下cookie就可以了。
CookieUtil.clearCookie(response);
这样就可以实现直接关闭就可以自动登录,而点击注销退出的话就取消自动登录。