@Override
	public UserDetails loadRememberMeInfo(SecurityServletContext context, String rememberMeKey, int maxAge) throws SecurityRuntimeException {
		try {
			String rememberMeCookieValue = null;
			Cookie[] cookies = context.getRequest().getCookies();
			if(null != cookies) {
				for(int i = 0; i < cookies.length; i++) {
					if(rememberMeKey.equals(cookies[i].getName())) {
						rememberMeCookieValue = cookies[i].getValue();
						break;
					}
				}
			}
			if(null != rememberMeCookieValue && rememberMeCookieValue.trim().length() > 0) {
				String one = new String(Base64Utils.decode(URLDecoder.decode(rememberMeCookieValue, "UTF-8").getBytes()));
				String[] parts = one.split(":");
				// parts
				// des:username, timeseq, md5:usernaem+timeseq+password
				if(parts.length == 3 && parts[0].length() > 0 && parts[1].length() > 0 && parts[2].length() > 0) {
					long timeSeq = -1L;
					try { timeSeq = Long.parseLong(parts[1]); } catch (NumberFormatException e) {}
					if (timeSeq == -1L || System.currentTimeMillis() - timeSeq > (maxAge * 1000)) {
						// 超时失效
						return null;
					}
					String username = EncryptUtils.DESDecrypt(parts[0], KEY);
					String password = queryPassword(username);
					if(null != password && password.length() > 0) {
						if(EncryptUtils.MD5Encode(username + ":" + parts[1] + ":" + password).equals(parts[2])) {
							// success
							return new SimpleUserDetails(username, password);
						}
					}
				}
			}
			
			return null;
		} catch (Exception e) {
			logger.warn("loadRememberMeDetails", e);
			throw new SecurityRuntimeException(e);
		}
	}