From 2f52e8c752122625f189ae7657e621db0d6d253c Mon Sep 17 00:00:00 2001
From: 李宇 <986321569@qq.com>
Date: 星期四, 28 一月 2021 09:39:19 +0800
Subject: [PATCH] 修改安全测评内容

---
 src/main/java/com/nanometer/smartlab/email/EmailSendSchedule.java                |    3 
 src/main/webapp/WEB-INF/spring-shiro.xml                                         |   47 ++
 src/main/java/com/nanometer/smartlab/api/schedule/ReagentSyncSchedule.java       |    6 
 src/main/java/com/nanometer/smartlab/realm/RetryLimitCredentialsMatcher.java     |   87 ++++
 src/main/java/com/nanometer/smartlab/service/OpeOrderServiceImpl.java            |    4 
 src/main/java/com/nanometer/smartlab/service/InterfaceServiceImpl.java           |    3 
 src/main/java/com/nanometer/smartlab/service/SysControllerServiceImpl.java       |    8 
 src/main/webapp/user_mng.xhtml                                                   |    3 
 src/main/java/com/nanometer/smartlab/api/schedule/UserPointSchedule.java         |    2 
 src/main/java/org/apache/shiro/web/filter/InvalidRequestFilter.java              |   88 ++--
 src/main/java/com/nanometer/smartlab/entity/OpeApply.java                        |    9 
 src/main/java/com/nanometer/smartlab/realm/ShiroDbRealm.java                     |  109 +++++
 src/main/java/org/springframework/web/filter/DelegatingFilterProxy.java          |  409 +++++++++++++++++++++
 src/main/java/com/nanometer/smartlab/api/ApiAction.java                          |   26 
 src/main/webapp/WEB-INF/spring-mvc.xml                                           |    7 
 src/main/webapp/index.xhtml                                                      |   12 
 src/main/java/com/nanometer/smartlab/realm/ShiroSpringCache.java                 |  113 +++++
 src/main/java/com/nanometer/smartlab/service/OpeReagentStatusServiceImpl.java    |    4 
 src/main/java/com/nanometer/smartlab/service/OpeApplyServiceImpl.java            |    4 
 src/main/java/com/nanometer/smartlab/realm/ShiroSpringCacheManager.java          |   63 +++
 src/main/java/com/nanometer/smartlab/controller/LoginController.java             |    4 
 src/main/java/com/nanometer/smartlab/util/Validator.java                         |   48 ++
 src/main/java/com/nanometer/smartlab/service/OpeUseFlowServiceImpl.java          |   10 
 src/main/java/com/nanometer/smartlab/service/OpeWarehouseReserveServiceImpl.java |   19 
 src/main/webapp/WEB-INF/test/test.properties                                     |    3 
 src/main/webapp/login.xhtml                                                      |    8 
 26 files changed, 990 insertions(+), 109 deletions(-)

diff --git a/src/main/java/com/nanometer/smartlab/api/ApiAction.java b/src/main/java/com/nanometer/smartlab/api/ApiAction.java
index 4ce057e..895fbec 100644
--- a/src/main/java/com/nanometer/smartlab/api/ApiAction.java
+++ b/src/main/java/com/nanometer/smartlab/api/ApiAction.java
@@ -28,6 +28,7 @@
 import org.apache.shiro.subject.Subject;
 import org.primefaces.context.RequestContext;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.servlet.ModelAndView;
@@ -49,46 +50,55 @@
 public class ApiAction extends BaseAction {
 
     private static Logger logger = Logger.getLogger(ApiAction.class);
-
+    @Lazy
     @Resource
     private SysUserService sysUserService;
+    @Lazy
     @Resource
     private OpeReagentStatusService opeReagentStatusService;
-    @Resource
-    private SysReagentService sysReagentService;
+    @Lazy
     @Resource
     private SysWarehouseContainerService sysWarehouseContainerService;
+    @Lazy
     @Resource
     private SysLaboratoryContainerService sysLaboratoryContainerService;
+    @Lazy
     @Resource
     private BaseMetaService baseMetaService;
+    @Lazy
     @Resource
     private InterfaceService interfaceService;
+    @Lazy
     @Resource
     private SysWarehouseService sysWarehouseService;
-
-    @Resource
-    private SysWarningService sysWarningService;
-
+    @Lazy
     @Resource
     private TempSensorsService tempSensorsService;
-
+    @Lazy
     @Resource
     private SysFileService sysFileService;
+    @Lazy
     @Resource
     private SysLaboratoryContainerDao sysLaboratoryContainerDao;
+    @Lazy
     @Resource
     private SysWarehouseContainerDao sysWarehouseContainerDao;
+    @Lazy
     @Resource
     private DangerousEncodeService dangerousEncodeService;
+    @Lazy
     @Resource
     private EncodeReplaceDictService encodeReplaceDictService;
+    @Lazy
     @Resource
     private SysLaboratoryService sysLaboratoryService;
+    @Lazy
     @Resource
     private HazardousWasteService hazardousWasteService;
+    @Lazy
     @Resource
     private OpeLaboratoryReserveService opeLaboratoryReserveService;
+    @Lazy
     @Resource
     private OpeUseFlowService opeUseFlowService;
     @Value("${institute.url}")
diff --git a/src/main/java/com/nanometer/smartlab/api/schedule/ReagentSyncSchedule.java b/src/main/java/com/nanometer/smartlab/api/schedule/ReagentSyncSchedule.java
index ac00ccf..347d7e2 100644
--- a/src/main/java/com/nanometer/smartlab/api/schedule/ReagentSyncSchedule.java
+++ b/src/main/java/com/nanometer/smartlab/api/schedule/ReagentSyncSchedule.java
@@ -7,6 +7,7 @@
 import org.apache.commons.lang.time.DateFormatUtils;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
@@ -40,14 +41,19 @@
     private String reagentStatusUrl;
     @Value("${sensors.url}")
     private String reagentSensorsUrl;
+    @Lazy
     @Resource
     private BaseMetaService baseMetaService;
+    @Lazy
     @Resource
     private OpeReagentStatusService reagentStatusService;
+    @Lazy
     @Resource
     private OpeUseFlowService opeUseFlowService;
+    @Lazy
     @Resource
     private SysContainerSensorsService sysContainerSensorsService;
+    @Lazy
     @Resource
     private SysUserService sysUserService;
 
diff --git a/src/main/java/com/nanometer/smartlab/api/schedule/UserPointSchedule.java b/src/main/java/com/nanometer/smartlab/api/schedule/UserPointSchedule.java
index e4f60c3..de15a9d 100644
--- a/src/main/java/com/nanometer/smartlab/api/schedule/UserPointSchedule.java
+++ b/src/main/java/com/nanometer/smartlab/api/schedule/UserPointSchedule.java
@@ -3,6 +3,7 @@
 import com.nanometer.smartlab.service.SysUserService;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
@@ -11,6 +12,7 @@
 @Component
 public class UserPointSchedule {
     private static Logger logger = Logger.getLogger(UserPointSchedule.class);
+    @Lazy
     @Autowired
     private SysUserService sysUserService;
 
diff --git a/src/main/java/com/nanometer/smartlab/controller/LoginController.java b/src/main/java/com/nanometer/smartlab/controller/LoginController.java
index 5b8f383..3ac1190 100644
--- a/src/main/java/com/nanometer/smartlab/controller/LoginController.java
+++ b/src/main/java/com/nanometer/smartlab/controller/LoginController.java
@@ -6,6 +6,7 @@
 import com.nanometer.smartlab.util.FacesUtils;
 import org.apache.log4j.Logger;
 import org.apache.shiro.authc.DisabledAccountException;
+import org.apache.shiro.authc.ExcessiveAttemptsException;
 import org.apache.shiro.authc.UnknownAccountException;
 import org.apache.shiro.authc.UsernamePasswordToken;
 import org.apache.shiro.subject.Subject;
@@ -42,6 +43,9 @@
         } catch (UnknownAccountException e) {
             FacesUtils.warn("用户名不存在");
             return null;
+        }  catch (ExcessiveAttemptsException e) {
+            FacesUtils.warn("登陆失败,密码连续输入错误超过5次,锁定5分钟!");
+            return null;
         } catch (Exception e) {
             logger.error("登陆失败", e);
         }
diff --git a/src/main/java/com/nanometer/smartlab/email/EmailSendSchedule.java b/src/main/java/com/nanometer/smartlab/email/EmailSendSchedule.java
index 3ae54f2..a88d64c 100644
--- a/src/main/java/com/nanometer/smartlab/email/EmailSendSchedule.java
+++ b/src/main/java/com/nanometer/smartlab/email/EmailSendSchedule.java
@@ -6,6 +6,7 @@
 import com.nanometer.smartlab.service.*;
 import com.nanometer.smartlab.util.EmailSend;
 import org.apache.log4j.Logger;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
@@ -17,7 +18,7 @@
  */
 @Component
 public class EmailSendSchedule {
-
+    @Lazy
     @Resource
     private OpeOrderService opeOrderService;
 
diff --git a/src/main/java/com/nanometer/smartlab/entity/OpeApply.java b/src/main/java/com/nanometer/smartlab/entity/OpeApply.java
index e2eba2e..ad696f2 100644
--- a/src/main/java/com/nanometer/smartlab/entity/OpeApply.java
+++ b/src/main/java/com/nanometer/smartlab/entity/OpeApply.java
@@ -2,6 +2,7 @@
 
 import com.nanometer.smartlab.entity.enumtype.ApplyStatus;
 import com.nanometer.smartlab.entity.enumtype.ValidFlag;
+import com.nanometer.smartlab.util.Validator;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
@@ -132,7 +133,7 @@
     }
 
     public void setApplyGoal(String applyGoal) {
-        this.applyGoal = applyGoal;
+        this.applyGoal = Validator.filter(applyGoal);
     }
 
     public String getId() {
@@ -156,7 +157,7 @@
     }
 
     public void setNum(Integer num) {
-        this.num = num;
+        this.num = Integer.parseInt(Validator.filter(num.toString()));
     }
 
     public String getApplyUserId() {
@@ -172,7 +173,7 @@
     }
 
     public void setObjective(String objective) {
-        this.objective = objective;
+        this.objective = Validator.filter(objective);
     }
 
     public Timestamp getCreateTime() {
@@ -210,7 +211,7 @@
         this.beforeApproveUserId=beforeApproveUserId;
     }
     public void setApproveUserId(String approveUserId) {
-        this.approveUserId = approveUserId;
+        this.approveUserId = Validator.filter(approveUserId);
     }
 
     public String getMemo() {
diff --git a/src/main/java/com/nanometer/smartlab/realm/RetryLimitCredentialsMatcher.java b/src/main/java/com/nanometer/smartlab/realm/RetryLimitCredentialsMatcher.java
new file mode 100644
index 0000000..7f5739c
--- /dev/null
+++ b/src/main/java/com/nanometer/smartlab/realm/RetryLimitCredentialsMatcher.java
@@ -0,0 +1,87 @@
+/**
+ * The MIT License (MIT)
+ * Copyright (c) 2016 Dreamlu (596392912@qq.com).
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.nanometer.smartlab.realm;
+
+import org.apache.log4j.Logger;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.ExcessiveAttemptsException;
+import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
+import org.apache.shiro.cache.Cache;
+import org.apache.shiro.cache.CacheManager;
+import org.springframework.beans.factory.InitializingBean;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * 输错5次密码锁定半小时,ehcache.xml配置
+ *
+ */
+public class RetryLimitCredentialsMatcher extends HashedCredentialsMatcher implements InitializingBean {
+	private final static Logger logger = Logger.getLogger(RetryLimitCredentialsMatcher.class);
+	private final static String DEFAULT_CHACHE_NAME = "retryLimitCache";
+
+	private final CacheManager cacheManager;
+	private String retryLimitCacheName;
+	private Cache<String, AtomicInteger> passwordRetryCache;
+
+	public RetryLimitCredentialsMatcher(CacheManager cacheManager) {
+		this.cacheManager = cacheManager;
+		this.retryLimitCacheName = DEFAULT_CHACHE_NAME;
+	}
+
+	public String getRetryLimitCacheName() {
+		return retryLimitCacheName;
+	}
+	public void setRetryLimitCacheName(String retryLimitCacheName) {
+		this.retryLimitCacheName = retryLimitCacheName;
+	}
+
+	@Override
+	public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) {
+		String username = (String) authcToken.getPrincipal();
+		//retry count + 1
+		AtomicInteger retryCount = passwordRetryCache.get(username);
+		if(retryCount == null) {
+			retryCount = new AtomicInteger(0);
+			passwordRetryCache.put(username, retryCount);
+		}
+		if(retryCount.incrementAndGet() > 5) {
+			//if retry count > 5 throw
+			logger.warn("username: " + username + " tried to login more than 5 times in period");
+//			FacesUtils.warn("用户名: " + username + " 密码连续输入错误超过5次,锁定5分钟!");
+			throw new ExcessiveAttemptsException("用户名: " + username + " 密码连续输入错误超过5次,锁定5分钟!");
+		}
+
+		boolean matches = super.doCredentialsMatch(authcToken, info);
+		if(matches) {
+			//clear retry data
+			passwordRetryCache.remove(username);
+		}
+		return matches;
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		this.passwordRetryCache = cacheManager.getCache(retryLimitCacheName);
+	}
+}
diff --git a/src/main/java/com/nanometer/smartlab/realm/ShiroDbRealm.java b/src/main/java/com/nanometer/smartlab/realm/ShiroDbRealm.java
new file mode 100644
index 0000000..83ca292
--- /dev/null
+++ b/src/main/java/com/nanometer/smartlab/realm/ShiroDbRealm.java
@@ -0,0 +1,109 @@
+package com.nanometer.smartlab.realm;
+
+import com.nanometer.smartlab.entity.BaseRolePage;
+import com.nanometer.smartlab.entity.SysUser;
+import com.nanometer.smartlab.service.BaseRolePageService;
+import com.nanometer.smartlab.service.SysUserService;
+import com.nanometer.smartlab.util.Constants;
+import org.apache.log4j.Logger;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authc.*;
+import org.apache.shiro.authc.credential.CredentialsMatcher;
+import org.apache.shiro.authz.AuthorizationInfo;
+import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.shiro.cache.Cache;
+import org.apache.shiro.cache.CacheManager;
+import org.apache.shiro.realm.AuthorizingRealm;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.apache.shiro.subject.SimplePrincipalCollection;
+import org.apache.shiro.subject.Subject;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @description:shiro权限认证
+ * @author:zhixuan.wang
+ * @date:2015/10/1 14:51
+ */
+public class ShiroDbRealm extends AuthorizingRealm {
+    private static Logger LOGGER = Logger.getLogger(ShiroDbRealm.class);
+
+    @Resource
+    private SysUserService sysUserService;
+    @Resource
+    private BaseRolePageService baseRolePageService;
+
+    public ShiroDbRealm(CacheManager cacheManager, CredentialsMatcher matcher) {
+        super(cacheManager, matcher);
+    }
+
+    /**
+     * Shiro登录认证(原理:用户提交 用户名和密码  --- shiro 封装令牌 ---- realm 通过用户名将密码查询返回 ---- shiro 自动去比较查询出密码和用户输入密码是否一致---- 进行登陆控制 )
+     */
+    @Override
+    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
+        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
+        final String account = String.valueOf(usernamePasswordToken.getUsername());
+        SysUser user = this.sysUserService.getSysUserByAccount(account);
+
+        if (user == null) {
+            throw new UnknownAccountException();
+        }
+
+        AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getAccount(), user.getPassword(), getName());
+
+        return authenticationInfo;
+    }
+
+    /**
+     * Shiro权限认证
+     */
+    @Override
+    protected AuthorizationInfo doGetAuthorizationInfo(
+            PrincipalCollection principals) {
+        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
+
+        String account = (String) super.getAvailablePrincipal(principals);
+        List<String> roles = new ArrayList<String>();
+        List<String> permissions = new ArrayList<String>();
+
+        SysUser user = this.sysUserService.getSysUserByAccount(account);
+        if(user != null && user.getRoleId() != null) {
+            roles.add(user.getRoleName());
+
+            List<BaseRolePage> baseRolePageList = baseRolePageService.getBaseRolePageList(user.getRoleId(), null);
+            if (baseRolePageList != null && baseRolePageList.size() > 0) {
+                for (BaseRolePage baseRolePage : baseRolePageList) {
+                    permissions.add(baseRolePage.getPageId());
+                }
+            }
+        }
+
+        info.addRoles(roles);
+        info.addStringPermissions(permissions);
+        return info;
+    }
+
+    @Override
+    public void onLogout(PrincipalCollection principals) {
+        Subject currentUser = SecurityUtils.getSubject();
+        currentUser.getSession(true).removeAttribute(Constants.SESSION_USER);
+        super.onLogout(principals);
+    }
+
+    /**
+     * 清除用户缓存
+     * @param loginName
+     */
+    public void removeUserCache(String loginName){
+        Cache<Object, AuthenticationInfo> cache = getAuthenticationCache();
+        if (null != cache){
+            cache.remove(loginName);
+        }
+        SimplePrincipalCollection principals = new SimplePrincipalCollection();
+        principals.add(loginName, super.getName());
+        super.clearCachedAuthenticationInfo(principals);
+    }
+}
diff --git a/src/main/java/com/nanometer/smartlab/realm/ShiroSpringCache.java b/src/main/java/com/nanometer/smartlab/realm/ShiroSpringCache.java
new file mode 100644
index 0000000..c961a51
--- /dev/null
+++ b/src/main/java/com/nanometer/smartlab/realm/ShiroSpringCache.java
@@ -0,0 +1,113 @@
+/**
+ * The MIT License (MIT)
+ * Copyright (c) 2016 Dreamlu (596392912@qq.com).
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.nanometer.smartlab.realm;
+
+import org.apache.log4j.Logger;
+import org.apache.shiro.cache.CacheException;
+import org.springframework.cache.Cache;
+import org.springframework.cache.Cache.ValueWrapper;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * 使用spring-cache作为shiro缓存
+ *
+ *
+ */
+@SuppressWarnings("unchecked")
+public class ShiroSpringCache<K, V> implements org.apache.shiro.cache.Cache<K, V> {
+	private static final Logger logger = Logger.getLogger(ShiroSpringCache.class);
+
+	private final Cache cache;
+
+	public ShiroSpringCache(Cache cache) {
+		if (cache == null) {
+			throw new IllegalArgumentException("Cache argument cannot be null.");
+		}
+		this.cache = cache;
+	}
+
+	@Override
+	public V get(K key) throws CacheException {
+		if (logger.isTraceEnabled()) {
+			logger.trace("Getting object from cache [" + this.cache.getName() + "] for key [" + key + "]key type:" + key.getClass());
+		}
+		ValueWrapper valueWrapper = cache.get(key);
+		if (valueWrapper == null) {
+			if (logger.isTraceEnabled()) {
+				logger.trace("Element for [" + key + "] is null.");
+			}
+			return null;
+		}
+		return (V) valueWrapper.get();
+	}
+
+	@Override
+	public V put(K key, V value) throws CacheException {
+		if (logger.isTraceEnabled()) {
+			logger.trace("Putting object in cache [" + this.cache.getName() + "] for key [" + key + "]key type:" + key.getClass());
+		}
+		V previous = get(key);
+		cache.put(key, value);
+		return previous;
+	}
+
+	@Override
+	public V remove(K key) throws CacheException {
+		if (logger.isTraceEnabled()) {
+			logger.trace("Removing object from cache [" + this.cache.getName() + "] for key [" + key + "]key type:" + key.getClass());
+		}
+		V previous = get(key);
+		cache.evict(key);
+		return previous;
+	}
+
+	@Override
+	public void clear() throws CacheException {
+		if (logger.isTraceEnabled()) {
+			logger.trace("Clearing all objects from cache [" + this.cache.getName() + "]");
+		}
+		cache.clear();
+	}
+
+	@Override
+	public int size() {
+		return 0;
+	}
+
+	@Override
+	public Set<K> keys() {
+		return Collections.emptySet();
+	}
+
+	@Override
+	public Collection<V> values() {
+		return Collections.emptySet();
+	}
+
+	@Override
+	public String toString() {
+		return "ShiroSpringCache [" + this.cache.getName() + "]";
+	}
+}
diff --git a/src/main/java/com/nanometer/smartlab/realm/ShiroSpringCacheManager.java b/src/main/java/com/nanometer/smartlab/realm/ShiroSpringCacheManager.java
new file mode 100644
index 0000000..982e707
--- /dev/null
+++ b/src/main/java/com/nanometer/smartlab/realm/ShiroSpringCacheManager.java
@@ -0,0 +1,63 @@
+/**
+ * The MIT License (MIT)
+ * Copyright (c) 2016 Dreamlu (596392912@qq.com).
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.nanometer.smartlab.realm;
+
+import org.apache.log4j.Logger;
+import org.apache.shiro.cache.Cache;
+import org.apache.shiro.cache.CacheException;
+import org.apache.shiro.cache.CacheManager;
+import org.apache.shiro.util.Destroyable;
+
+/**
+ * 使用spring-cache作为shiro缓存
+ * 缓存管理器
+ * @author L.cm
+ *
+ */
+public class ShiroSpringCacheManager implements CacheManager, Destroyable {
+	private static final Logger logger = Logger.getLogger(ShiroSpringCacheManager.class);
+
+	private org.springframework.cache.CacheManager cacheManager;
+
+	public org.springframework.cache.CacheManager getCacheManager() {
+		return cacheManager;
+	}
+
+	public void setCacheManager(org.springframework.cache.CacheManager cacheManager) {
+		this.cacheManager = cacheManager;
+	}
+
+	@Override
+	public <K, V> Cache<K, V> getCache(String name) throws CacheException {
+		if (logger.isTraceEnabled()) {
+			logger.trace("Acquiring ShiroSpringCache instance named [" + name + "]");
+		}
+		org.springframework.cache.Cache cache = cacheManager.getCache(name);
+		return new ShiroSpringCache<K, V>(cache);
+	}
+
+	@Override
+	public void destroy() throws Exception {
+		cacheManager = null;
+	}
+
+}
diff --git a/src/main/java/com/nanometer/smartlab/service/InterfaceServiceImpl.java b/src/main/java/com/nanometer/smartlab/service/InterfaceServiceImpl.java
index d197cf3..2a393df 100644
--- a/src/main/java/com/nanometer/smartlab/service/InterfaceServiceImpl.java
+++ b/src/main/java/com/nanometer/smartlab/service/InterfaceServiceImpl.java
@@ -22,6 +22,7 @@
 import org.apache.http.util.EntityUtils;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
@@ -39,7 +40,7 @@
 public class InterfaceServiceImpl implements InterfaceService {
 
     private static Logger logger = Logger.getLogger(ApiAction.class);
-
+    @Lazy
 	@Resource
 	private OpeUseFlowService opeUseFlowService;
 	@Resource
diff --git a/src/main/java/com/nanometer/smartlab/service/OpeApplyServiceImpl.java b/src/main/java/com/nanometer/smartlab/service/OpeApplyServiceImpl.java
index 4f09cda..9924439 100644
--- a/src/main/java/com/nanometer/smartlab/service/OpeApplyServiceImpl.java
+++ b/src/main/java/com/nanometer/smartlab/service/OpeApplyServiceImpl.java
@@ -15,6 +15,7 @@
 import com.nanometer.smartlab.util.MessageUtil;
 import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.dao.DataAccessException;
 import org.springframework.dao.DataIntegrityViolationException;
 import org.springframework.dao.DuplicateKeyException;
@@ -41,10 +42,13 @@
 
     @Resource(name = "opeApplyDao")
     OpeApplyDao opeApplyDao;
+    @Lazy
     @Resource
     OpeOrderService opeOrderService;
+    @Lazy
     @Resource
     OpeReagentStatusService opeReagentStatusService;
+    @Lazy
     @Resource
     OpeWarehouseReserveService opeWarehouseReserveService;
 
diff --git a/src/main/java/com/nanometer/smartlab/service/OpeOrderServiceImpl.java b/src/main/java/com/nanometer/smartlab/service/OpeOrderServiceImpl.java
index 50ce804..ea1518d 100644
--- a/src/main/java/com/nanometer/smartlab/service/OpeOrderServiceImpl.java
+++ b/src/main/java/com/nanometer/smartlab/service/OpeOrderServiceImpl.java
@@ -17,6 +17,7 @@
 import com.nanometer.smartlab.util.MessageUtil;
 import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.dao.DataAccessException;
 import org.springframework.dao.DataIntegrityViolationException;
 import org.springframework.dao.DuplicateKeyException;
@@ -49,10 +50,13 @@
     private SysSequenceService sysSequenceService;
     @Resource
     private OpeApplyService opeApplyService;
+    @Lazy
     @Resource
     private OpeReagentStatusService opeReagentStatusService;
+    @Lazy
     @Resource
     private OpeWarehouseReserveService opeWarehouseReserveService;
+    @Lazy
     @Resource
     private OpeUseFlowService opeUseFlowService;
     @Resource
diff --git a/src/main/java/com/nanometer/smartlab/service/OpeReagentStatusServiceImpl.java b/src/main/java/com/nanometer/smartlab/service/OpeReagentStatusServiceImpl.java
index 30b76c3..c3ab8f4 100644
--- a/src/main/java/com/nanometer/smartlab/service/OpeReagentStatusServiceImpl.java
+++ b/src/main/java/com/nanometer/smartlab/service/OpeReagentStatusServiceImpl.java
@@ -12,6 +12,7 @@
 import com.nanometer.smartlab.entity.enumtype.ValidFlag;
 import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.dao.DataAccessException;
 import org.springframework.dao.DataIntegrityViolationException;
 import org.springframework.dao.DuplicateKeyException;
@@ -40,9 +41,10 @@
 
 	@Resource(name = "opeReagentStatusDao")
 	OpeReagentStatusDao opeReagentStatusDao;
-
+	@Lazy
 	@Resource
 	private OpeWarehouseReserveService opeWarehouseReserveService;
+	@Lazy
 	@Resource
 	private OpeUseFlowService opeUseFlowService;
 	@Resource
diff --git a/src/main/java/com/nanometer/smartlab/service/OpeUseFlowServiceImpl.java b/src/main/java/com/nanometer/smartlab/service/OpeUseFlowServiceImpl.java
index 2d7ab3e..e0a4ccb 100644
--- a/src/main/java/com/nanometer/smartlab/service/OpeUseFlowServiceImpl.java
+++ b/src/main/java/com/nanometer/smartlab/service/OpeUseFlowServiceImpl.java
@@ -55,8 +55,6 @@
     @Resource
     private OpeReagentStatusService opeReagentStatusService;
     @Resource
-    private OpeUseFlowService opeUseFlowService;
-    @Resource
     private SysReagentService sysReagentService;
     @Resource
     private BaseMetaDao baseMetaDao;
@@ -389,11 +387,11 @@
                 for (String statusId : codeTmp) {
                     String code = opeReagentStatusService.getOpeReagentStatus(statusId).getReagentCode();
                     //此时状态为领用待入库
-                    opeUseFlowService.updateReceiptNumber(code, receiptNumber);
+                    this.updateReceiptNumber(code, receiptNumber);
                 }
             }else{
                 for (String code : codeTmp) {
-                    opeUseFlowService.updateReceiptNumber(code, receiptNumber);
+                    this.updateReceiptNumber(code, receiptNumber);
                 }
             }
 
@@ -443,11 +441,11 @@
                 for (String statusId : codeTmp) {
                     String code = opeReagentStatusService.getOpeReagentStatus(statusId).getReagentCode();
                     //此时状态为领用待入库
-                    opeUseFlowService.updateReceiptNumber(code, receiptNumber);
+                    this.updateReceiptNumber(code, receiptNumber);
                 }
             }else{
                 for (String code : codeTmp) {
-                    opeUseFlowService.updateReceiptNumber(code, receiptNumber);
+                    this.updateReceiptNumber(code, receiptNumber);
                 }
             }
 
diff --git a/src/main/java/com/nanometer/smartlab/service/OpeWarehouseReserveServiceImpl.java b/src/main/java/com/nanometer/smartlab/service/OpeWarehouseReserveServiceImpl.java
index c26f32f..18fc0ef 100644
--- a/src/main/java/com/nanometer/smartlab/service/OpeWarehouseReserveServiceImpl.java
+++ b/src/main/java/com/nanometer/smartlab/service/OpeWarehouseReserveServiceImpl.java
@@ -48,8 +48,6 @@
 
     @Resource
     private OpeUseFlowService opeUseFlowService;
-    @Resource
-    private OpeWarehouseReserveService opeWarehouseReserveService;
 
     @Resource(name="baseMetaDao")
     private BaseMetaDao baseMetaDao;
@@ -596,8 +594,7 @@
 	@Transactional
     public void insertOpeWarehouseReserve2(OpeApplyReserve opeApplyReserve, OpeOrder oo) {
 
-		OpeWarehouseReserve ope = this.opeWarehouseReserveService
-				.getOpeWarehouseReserve2(opeApplyReserve.getReagent().getId(), opeApplyReserve.getArticleNumber(),opeApplyReserve.getHouseId());
+		OpeWarehouseReserve ope = this.getOpeWarehouseReserve2(opeApplyReserve.getReagent().getId(), opeApplyReserve.getArticleNumber(),opeApplyReserve.getHouseId());
 		if (ope == null) {
 
 			ope = new OpeWarehouseReserve();
@@ -619,7 +616,7 @@
 			opeWarehouseReserveDao.insertOpeWarehouseReserve2(ope);
 		}else {
 			ope.setReserve(ope.getReserve() + opeApplyReserve.getArrivalNum());
-			this.opeWarehouseReserveService.updateOpeWarehouseReserve(ope);
+			this.updateOpeWarehouseReserve(ope);
 		}
 
 
@@ -686,7 +683,7 @@
 			List<OpeWarehouseReserve> cacheUpdateList = oar.getCacheUpdateList();
 			for (OpeWarehouseReserve owr : cacheUpdateList) {
 				//1.根据仓库id和试剂id搜索不同批号的试剂库存
-				List<OpeWarehouseReserve> reserveList = opeWarehouseReserveService
+				List<OpeWarehouseReserve> reserveList = this
 						.selectWarehouseByRidAndArticleNumberAndWarehouse(reagentId, owr.getArticleNumber(), owr.getWarehouseId());
 				Integer numLeave = owr.getUseNum();
 
@@ -730,9 +727,9 @@
 
 					}
 
-					
+
 					//更新库存
-					opeWarehouseReserveService.updateBtReserve(warehouseReserve.getId(),usedNum);
+					this.updateBtReserve(warehouseReserve.getId(),usedNum);
 					if (numLeave < 1) {
 						break;
 					}
@@ -819,7 +816,7 @@
 
 
             // 仓库库存update
-            opeWarehouseReserve = this.opeWarehouseReserveService.getOpeWarehouseReserve2(opeApply.getReagent().getId(), opeApply.getArticleNumber(),opeApply.getHouseId());
+            opeWarehouseReserve = this.getOpeWarehouseReserve2(opeApply.getReagent().getId(), opeApply.getArticleNumber(),opeApply.getHouseId());
             if (opeWarehouseReserve == null) {
                 opeWarehouseReserve = new OpeWarehouseReserve();
                 opeWarehouseReserve.setReagentId(opeApply.getReagent().getId());
@@ -830,9 +827,9 @@
             }
             opeWarehouseReserve.setReserve(opeWarehouseReserve.getReserve() + opeApply.getArrivalNum());
             if (StringUtils.isBlank(opeWarehouseReserve.getId())) {
-                this.opeWarehouseReserveService.insertOpeWarehouseReserve(opeWarehouseReserve);
+                this.insertOpeWarehouseReserve(opeWarehouseReserve);
             } else {
-                this.opeWarehouseReserveService.updateOpeWarehouseReserve(opeWarehouseReserve);
+                this.updateOpeWarehouseReserve(opeWarehouseReserve);
             }
         }
 	}
diff --git a/src/main/java/com/nanometer/smartlab/service/SysControllerServiceImpl.java b/src/main/java/com/nanometer/smartlab/service/SysControllerServiceImpl.java
index 4c5aa0e..5a6321b 100644
--- a/src/main/java/com/nanometer/smartlab/service/SysControllerServiceImpl.java
+++ b/src/main/java/com/nanometer/smartlab/service/SysControllerServiceImpl.java
@@ -38,8 +38,6 @@
 	SysControllerDao sysControllerDao;
 	@Resource(name = "sysLaboratoryContainerDao")
 	SysLaboratoryContainerDao sysLaboratoryContainerDao;
-	@Resource(name = "sysControllerService")
-	SysControllerService sysControllerService;
 	@Resource(name = "baseMetaService")
 	BaseMetaService baseMetaService;
 	@Override
@@ -62,7 +60,7 @@
 			throw new BusinessException(ExceptionEnumCode.DB_ERR,
 					MessageUtil.getMessageByCode(ExceptionEnumCode.DB_ERR.getCode()), e);
 		}
-		
+
 	}
 
 	@Override
@@ -114,7 +112,7 @@
 
     @Override
     public void uploadFile(FileUploadEvent event) throws  Exception{
-		List<SysController> sysControllers=sysControllerService.getAllControllerList();
+		List<SysController> sysControllers=this.getAllControllerList();
 		List<BaseMeta> typeList=baseMetaService.getBaseMetaList("controller_type");
 		//主控名字和条码
 		HashSet<String> controllerInfo = new HashSet<>();
@@ -196,7 +194,7 @@
 				sysController.setControllerCode(controlCode);
 				sysController.setControllerName(controlName);
 				sysController.setType(typeMap.get(controlType));
-				sysControllerService.insertSysController(sysController);
+				this.insertSysController(sysController);
 				controllerInfo.add(controlName);
 				controllerInfo.add(controlCode);
 			}
diff --git a/src/main/java/com/nanometer/smartlab/util/Validator.java b/src/main/java/com/nanometer/smartlab/util/Validator.java
new file mode 100644
index 0000000..ccc4e60
--- /dev/null
+++ b/src/main/java/com/nanometer/smartlab/util/Validator.java
@@ -0,0 +1,48 @@
+package com.nanometer.smartlab.util;
+
+public class Validator {
+    public static String filter(String value) {
+        if (value == null) {
+            return null;
+        }
+        StringBuffer result = new StringBuffer(value.length());
+        for (int i = 0; i < value.length(); ++i){
+            switch (value.charAt(i)) {
+                case '<':
+                    result.append("&lt;");
+                    break;
+                case '>':
+                    result.append("&gt;");
+                    break;
+                case '"':
+                    result.append("&quot;");
+                    break;
+                case '\'':
+                    result.append("&#39;");
+                    break;
+                case '%':
+                    result.append("&#37;");
+                    break;
+                case ';':
+                    result.append("&#59;");
+                    break;
+                case '(':
+                    result.append("&#40;");
+                    break;
+                case ')':
+                    result.append("&#41;");
+                    break;
+                case '&':
+                    result.append("&amp;");
+                    break;
+                case '+':
+                    result.append("&#43;");
+                    break;
+                default:
+                    result.append(value.charAt(i));
+                    break;
+            }
+        }
+        return result.toString().replaceAll("\\\\","").replaceAll("/", "");
+    }
+}
diff --git a/src/main/java/org/apache/shiro/web/filter/InvalidRequestFilter.java b/src/main/java/org/apache/shiro/web/filter/InvalidRequestFilter.java
index 48fcb2e..b697690 100644
--- a/src/main/java/org/apache/shiro/web/filter/InvalidRequestFilter.java
+++ b/src/main/java/org/apache/shiro/web/filter/InvalidRequestFilter.java
@@ -86,50 +86,50 @@
                 ctx = WebUtils.toHttp(request).getContextPath();
             }
             // 登录url拼接的jsessionId进行放行
-            if(uri.startsWith(ctx + this.getLoginUrl() + ";jsessionid=") ||
-                    uri.startsWith(ctx + this.getLoginUrl() + "%3bjsessionid=") ||
-                    uri.startsWith(ctx + this.getLoginUrl() + "%3Bjsessionid=") ||
-                    uri.startsWith(ctx + "/javax.faces.resource/mybootstrap.css.xhtml;jsessionid=")||
-                    uri.startsWith(ctx + "/javax.faces.resource/mybootstrap.css.xhtml%3bjsessionid=")||
-                    uri.startsWith(ctx + "/javax.faces.resource/mybootstrap.css.xhtml%3Bjsessionid=")||
-
-                    uri.startsWith(ctx + "/javax.faces.resource/default.css.xhtml;jsessionid=")||
-                    uri.startsWith(ctx + "/javax.faces.resource/default.css.xhtml%3bjsessionid=")||
-                    uri.startsWith(ctx + "/javax.faces.resource/default.css.xhtml%3Bjsessionid=")||
-
-                    uri.startsWith(ctx + "/javax.faces.resource/components.css.xhtml;jsessionid=")||
-                    uri.startsWith(ctx + "/javax.faces.resource/components.css.xhtml%3bjsessionid=")||
-                    uri.startsWith(ctx + "/javax.faces.resource/components.css.xhtml%3Bjsessionid=")||
-
-                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery-plugins.js.xhtml;jsessionid=")||
-                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery-plugins.js.xhtml%3bjsessionid=")||
-                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery-plugins.js.xhtml%3Bjsessionid=")||
-
-                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery.js.xhtml;jsessionid=")||
-                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery.js.xhtml%3bjsessionid=")||
-                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery.js.xhtml%3Bjsessionid=")||
-
-                    uri.startsWith(ctx + "/javax.faces.resource/core.js.xhtml;jsessionid=")||
-                    uri.startsWith(ctx + "/javax.faces.resource/core.js.xhtml%3bjsessionid=")||
-                    uri.startsWith(ctx + "/javax.faces.resource/core.js.xhtml%3Bjsessionid=")||
-
-                    uri.startsWith(ctx + "/javax.faces.resource/extra.js.xhtml;jsessionid=")||
-                    uri.startsWith(ctx + "/javax.faces.resource/extra.js.xhtml%3bjsessionid=")||
-                    uri.startsWith(ctx + "/javax.faces.resource/extra.js.xhtml%3Bjsessionid=")||
-
-                    uri.startsWith(ctx + "/resources/images/logo1.png;jsessionid=")||
-                    uri.startsWith(ctx + "/resources/images/logo1.png%3bjsessionid=")||
-                    uri.startsWith(ctx + "/resources/images/logo1.png%3Bjsessionid=")||
-
-                    uri.startsWith(ctx + "/javax.faces.resource/components.js.xhtml;jsessionid=")||
-                    uri.startsWith(ctx + "/javax.faces.resource/components.js.xhtml%3bjsessionid=")||
-                    uri.startsWith(ctx + "/javax.faces.resource/components.js.xhtml%3Bjsessionid=")||
-
-                    uri.startsWith(ctx + "/resources/images/logo.png;jsessionid=")||
-                    uri.startsWith(ctx + "/resources/images/logo.png%3bjsessionid=")||
-                    uri.startsWith(ctx + "/resources/images/logo.png%3Bjsessionid=")) {
-                return false;
-            }
+//            if(uri.startsWith(ctx + this.getLoginUrl() + ";jsessionid=") ||
+//                    uri.startsWith(ctx + this.getLoginUrl() + "%3bjsessionid=") ||
+//                    uri.startsWith(ctx + this.getLoginUrl() + "%3Bjsessionid=") ||
+//                    uri.startsWith(ctx + "/javax.faces.resource/mybootstrap.css.xhtml;jsessionid=")||
+//                    uri.startsWith(ctx + "/javax.faces.resource/mybootstrap.css.xhtml%3bjsessionid=")||
+//                    uri.startsWith(ctx + "/javax.faces.resource/mybootstrap.css.xhtml%3Bjsessionid=")||
+//
+//                    uri.startsWith(ctx + "/javax.faces.resource/default.css.xhtml;jsessionid=")||
+//                    uri.startsWith(ctx + "/javax.faces.resource/default.css.xhtml%3bjsessionid=")||
+//                    uri.startsWith(ctx + "/javax.faces.resource/default.css.xhtml%3Bjsessionid=")||
+//
+//                    uri.startsWith(ctx + "/javax.faces.resource/components.css.xhtml;jsessionid=")||
+//                    uri.startsWith(ctx + "/javax.faces.resource/components.css.xhtml%3bjsessionid=")||
+//                    uri.startsWith(ctx + "/javax.faces.resource/components.css.xhtml%3Bjsessionid=")||
+//
+//                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery-plugins.js.xhtml;jsessionid=")||
+//                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery-plugins.js.xhtml%3bjsessionid=")||
+//                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery-plugins.js.xhtml%3Bjsessionid=")||
+//
+//                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery.js.xhtml;jsessionid=")||
+//                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery.js.xhtml%3bjsessionid=")||
+//                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery.js.xhtml%3Bjsessionid=")||
+//
+//                    uri.startsWith(ctx + "/javax.faces.resource/core.js.xhtml;jsessionid=")||
+//                    uri.startsWith(ctx + "/javax.faces.resource/core.js.xhtml%3bjsessionid=")||
+//                    uri.startsWith(ctx + "/javax.faces.resource/core.js.xhtml%3Bjsessionid=")||
+//
+//                    uri.startsWith(ctx + "/javax.faces.resource/extra.js.xhtml;jsessionid=")||
+//                    uri.startsWith(ctx + "/javax.faces.resource/extra.js.xhtml%3bjsessionid=")||
+//                    uri.startsWith(ctx + "/javax.faces.resource/extra.js.xhtml%3Bjsessionid=")||
+//
+//                    uri.startsWith(ctx + "/resources/images/logo1.png;jsessionid=")||
+//                    uri.startsWith(ctx + "/resources/images/logo1.png%3bjsessionid=")||
+//                    uri.startsWith(ctx + "/resources/images/logo1.png%3Bjsessionid=")||
+//
+//                    uri.startsWith(ctx + "/javax.faces.resource/components.js.xhtml;jsessionid=")||
+//                    uri.startsWith(ctx + "/javax.faces.resource/components.js.xhtml%3bjsessionid=")||
+//                    uri.startsWith(ctx + "/javax.faces.resource/components.js.xhtml%3Bjsessionid=")||
+//
+//                    uri.startsWith(ctx + "/resources/images/logo.png;jsessionid=")||
+//                    uri.startsWith(ctx + "/resources/images/logo.png%3bjsessionid=")||
+//                    uri.startsWith(ctx + "/resources/images/logo.png%3Bjsessionid=")) {
+//                return false;
+//            }
             return SEMICOLON.stream().anyMatch(uri::contains);
         }
         return false;
diff --git a/src/main/java/org/springframework/web/filter/DelegatingFilterProxy.java b/src/main/java/org/springframework/web/filter/DelegatingFilterProxy.java
new file mode 100644
index 0000000..6c74c45
--- /dev/null
+++ b/src/main/java/org/springframework/web/filter/DelegatingFilterProxy.java
@@ -0,0 +1,409 @@
+/*
+ * Copyright 2002-2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.web.filter;
+
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.WebApplicationContextUtils;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Proxy for a standard Servlet Filter, delegating to a Spring-managed bean that
+ * implements the Filter interface. Supports a "targetBeanName" filter init-param
+ * in {@code web.xml}, specifying the name of the target bean in the Spring
+ * application context.
+ *
+ * <p>{@code web.xml} will usually contain a {@code DelegatingFilterProxy} definition,
+ * with the specified {@code filter-name} corresponding to a bean name in
+ * Spring's root application context. All calls to the filter proxy will then
+ * be delegated to that bean in the Spring context, which is required to implement
+ * the standard Servlet Filter interface.
+ *
+ * <p>This approach is particularly useful for Filter implementation with complex
+ * setup needs, allowing to apply the full Spring bean definition machinery to
+ * Filter instances. Alternatively, consider standard Filter setup in combination
+ * with looking up service beans from the Spring root application context.
+ *
+ * <p><b>NOTE:</b> The lifecycle methods defined by the Servlet Filter interface
+ * will by default <i>not</i> be delegated to the target bean, relying on the
+ * Spring application context to manage the lifecycle of that bean. Specifying
+ * the "targetFilterLifecycle" filter init-param as "true" will enforce invocation
+ * of the {@code Filter.init} and {@code Filter.destroy} lifecycle methods
+ * on the target bean, letting the servlet container manage the filter lifecycle.
+ *
+ * <p>As of Spring 3.1, {@code DelegatingFilterProxy} has been updated to optionally accept
+ * constructor parameters when using Servlet 3.0's instance-based filter registration
+ * methods, usually in conjunction with Spring 3.1's
+ * {@link org.springframework.web.WebApplicationInitializer} SPI. These constructors allow
+ * for providing the delegate Filter bean directly, or providing the application context
+ * and bean name to fetch, avoiding the need to look up the application context from the
+ * ServletContext.
+ *
+ * <p>This class was originally inspired by Spring Security's {@code FilterToBeanProxy}
+ * class, written by Ben Alex.
+ *
+ * @author Juergen Hoeller
+ * @author Sam Brannen
+ * @author Chris Beams
+ * @since 1.2
+ * @see #setTargetBeanName
+ * @see #setTargetFilterLifecycle
+ * @see Filter#doFilter
+ * @see Filter#init
+ * @see Filter#destroy
+ * @see #DelegatingFilterProxy(Filter)
+ * @see #DelegatingFilterProxy(String)
+ * @see #DelegatingFilterProxy(String, WebApplicationContext)
+ * @see org.springframework.web.WebApplicationInitializer
+ */
+public class DelegatingFilterProxy extends GenericFilterBean {
+
+    private String contextAttribute;
+
+    private WebApplicationContext webApplicationContext;
+
+    private String targetBeanName;
+
+    private boolean targetFilterLifecycle = false;
+
+    private volatile Filter delegate;
+
+    private final Object delegateMonitor = new Object();
+
+
+    /**
+     * Create a new {@code DelegatingFilterProxy}. For traditional (pre-Servlet 3.0) use
+     * in {@code web.xml}.
+     * @see #setTargetBeanName(String)
+     */
+    public DelegatingFilterProxy() {
+    }
+
+    /**
+     * Create a new {@code DelegatingFilterProxy} with the given {@link Filter} delegate.
+     * Bypasses entirely the need for interacting with a Spring application context,
+     * specifying the {@linkplain #setTargetBeanName target bean name}, etc.
+     * <p>For use in Servlet 3.0+ environments where instance-based registration of
+     * filters is supported.
+     * @param delegate the {@code Filter} instance that this proxy will delegate to and
+     * manage the lifecycle for (must not be {@code null}).
+     * @see #doFilter(ServletRequest, ServletResponse, FilterChain)
+     * @see #invokeDelegate(Filter, ServletRequest, ServletResponse, FilterChain)
+     * @see #destroy()
+     * @see #setEnvironment(org.springframework.core.env.Environment)
+     */
+    public DelegatingFilterProxy(Filter delegate) {
+        Assert.notNull(delegate, "Delegate Filter must not be null");
+        this.delegate = delegate;
+    }
+
+    /**
+     * Create a new {@code DelegatingFilterProxy} that will retrieve the named target
+     * bean from the Spring {@code WebApplicationContext} found in the {@code ServletContext}
+     * (either the 'root' application context or the context named by
+     * {@link #setContextAttribute}).
+     * <p>For use in Servlet 3.0+ environments where instance-based registration of
+     * filters is supported.
+     * <p>The target bean must implement the standard Servlet Filter.
+     * @param targetBeanName name of the target filter bean to look up in the Spring
+     * application context (must not be {@code null}).
+     * @see #findWebApplicationContext()
+     * @see #setEnvironment(org.springframework.core.env.Environment)
+     */
+    public DelegatingFilterProxy(String targetBeanName) {
+        this(targetBeanName, null);
+    }
+
+    /**
+     * Create a new {@code DelegatingFilterProxy} that will retrieve the named target
+     * bean from the given Spring {@code WebApplicationContext}.
+     * <p>For use in Servlet 3.0+ environments where instance-based registration of
+     * filters is supported.
+     * <p>The target bean must implement the standard Servlet Filter interface.
+     * <p>The given {@code WebApplicationContext} may or may not be refreshed when passed
+     * in. If it has not, and if the context implements {@link ConfigurableApplicationContext},
+     * a {@link ConfigurableApplicationContext#refresh() refresh()} will be attempted before
+     * retrieving the named target bean.
+     * <p>This proxy's {@code Environment} will be inherited from the given
+     * {@code WebApplicationContext}.
+     * @param targetBeanName name of the target filter bean in the Spring application
+     * context (must not be {@code null}).
+     * @param wac the application context from which the target filter will be retrieved;
+     * if {@code null}, an application context will be looked up from {@code ServletContext}
+     * as a fallback.
+     * @see #findWebApplicationContext()
+     * @see #setEnvironment(org.springframework.core.env.Environment)
+     */
+    public DelegatingFilterProxy(String targetBeanName, WebApplicationContext wac) {
+        Assert.hasText(targetBeanName, "Target Filter bean name must not be null or empty");
+        this.setTargetBeanName(targetBeanName);
+        this.webApplicationContext = wac;
+        if (wac != null) {
+            this.setEnvironment(wac.getEnvironment());
+        }
+    }
+
+    /**
+     * Set the name of the ServletContext attribute which should be used to retrieve the
+     * {@link WebApplicationContext} from which to load the delegate {@link Filter} bean.
+     */
+    public void setContextAttribute(String contextAttribute) {
+        this.contextAttribute = contextAttribute;
+    }
+
+    /**
+     * Return the name of the ServletContext attribute which should be used to retrieve the
+     * {@link WebApplicationContext} from which to load the delegate {@link Filter} bean.
+     */
+    public String getContextAttribute() {
+        return this.contextAttribute;
+    }
+
+    /**
+     * Set the name of the target bean in the Spring application context.
+     * The target bean must implement the standard Servlet Filter interface.
+     * <p>By default, the {@code filter-name} as specified for the
+     * DelegatingFilterProxy in {@code web.xml} will be used.
+     */
+    public void setTargetBeanName(String targetBeanName) {
+        this.targetBeanName = targetBeanName;
+    }
+
+    /**
+     * Return the name of the target bean in the Spring application context.
+     */
+    protected String getTargetBeanName() {
+        return this.targetBeanName;
+    }
+
+    /**
+     * Set whether to invoke the {@code Filter.init} and
+     * {@code Filter.destroy} lifecycle methods on the target bean.
+     * <p>Default is "false"; target beans usually rely on the Spring application
+     * context for managing their lifecycle. Setting this flag to "true" means
+     * that the servlet container will control the lifecycle of the target
+     * Filter, with this proxy delegating the corresponding calls.
+     */
+    public void setTargetFilterLifecycle(boolean targetFilterLifecycle) {
+        this.targetFilterLifecycle = targetFilterLifecycle;
+    }
+
+    /**
+     * Return whether to invoke the {@code Filter.init} and
+     * {@code Filter.destroy} lifecycle methods on the target bean.
+     */
+    protected boolean isTargetFilterLifecycle() {
+        return this.targetFilterLifecycle;
+    }
+
+
+    @Override
+    protected void initFilterBean() throws ServletException {
+        synchronized (this.delegateMonitor) {
+            if (this.delegate == null) {
+                // If no target bean name specified, use filter name.
+                if (this.targetBeanName == null) {
+                    this.targetBeanName = getFilterName();
+                }
+                // Fetch Spring root application context and initialize the delegate early,
+                // if possible. If the root application context will be started after this
+                // filter proxy, we'll have to resort to lazy initialization.
+                WebApplicationContext wac = findWebApplicationContext();
+                if (wac != null) {
+                    this.delegate = initDelegate(wac);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
+            throws ServletException, IOException {
+        String referer = ((HttpServletRequest)request).getHeader("Referer");
+        StringBuffer stringBuffer = new StringBuffer();
+        stringBuffer.append(request.getScheme()).append("://").append(request.getServerName());
+        if(referer != null && !referer.equals("") ){
+            if(referer.lastIndexOf(String.valueOf(stringBuffer)) != 0){
+                HttpServletResponse httpResp1 = (HttpServletResponse)response;
+                httpResp1.setStatus(500);
+                httpResp1.setContentType("text/html; charset=utf-8");
+                httpResp1.getWriter().write("系统不支持当前域名的访问!");
+                return;
+            }
+        }
+
+        String method = ((HttpServletRequest)request).getMethod();
+        if (method.toUpperCase().equals("OPTIONS")){
+            HttpServletResponse httpResp1 = (HttpServletResponse)response;
+            httpResp1.setStatus(500);
+            httpResp1.setContentType("text/html; charset=utf-8");
+            httpResp1.getWriter().write("系统不支持访问!");
+            return;
+        }
+
+        String contentType = ((HttpServletRequest)request).getHeader("Content-Type");
+        if ((method.toUpperCase().equals("GET") && !StringUtils.isEmpty(contentType) && contentType.contains("form"))||
+                (StringUtils.isEmpty(contentType) && method.toUpperCase().equals("POST"))){
+            HttpServletResponse httpResp1 = (HttpServletResponse)response;
+            httpResp1.setStatus(500);
+            httpResp1.setContentType("text/html; charset=utf-8");
+            httpResp1.getWriter().write("系统不支持访问!");
+            return;
+        }
+
+
+        HttpServletRequest httpReq = (HttpServletRequest) request;
+        HttpServletResponse httpRes = (HttpServletResponse) response;
+
+        /**禁止缓存**/
+        httpRes.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
+        httpRes.setHeader("Pragma", "no-cache");
+        httpRes.setHeader("X-Content-Type-Options", "nosniff");
+        httpRes.setHeader("X-XSS-Protection", "1");
+        httpRes.setHeader("strict-transport-security", "max-age=31536000");
+        httpRes.setHeader("X-Frame-Options", "DENY");
+
+        //安全测评需要,如影响使用请注释掉
+        if(httpReq.getRequestURI().contains("javax.faces.resource")){
+            httpRes.setHeader("Content-Security-Policy", "default-src 'self';script-src 'self';frame-ancestors 'self';");
+        }
+
+        // Lazily initialize the delegate if necessary.
+        Filter delegateToUse = this.delegate;
+        if (delegateToUse == null) {
+            synchronized (this.delegateMonitor) {
+                delegateToUse = this.delegate;
+                if (delegateToUse == null) {
+                    WebApplicationContext wac = findWebApplicationContext();
+                    if (wac == null) {
+                        throw new IllegalStateException("No WebApplicationContext found: " +
+                                "no ContextLoaderListener or DispatcherServlet registered?");
+                    }
+                    delegateToUse = initDelegate(wac);
+                }
+                this.delegate = delegateToUse;
+            }
+        }
+
+        // Let the delegate perform the actual doFilter operation.
+        invokeDelegate(delegateToUse, request, response, filterChain);
+    }
+
+    @Override
+    public void destroy() {
+        Filter delegateToUse = this.delegate;
+        if (delegateToUse != null) {
+            destroyDelegate(delegateToUse);
+        }
+    }
+
+
+    /**
+     * Return the {@code WebApplicationContext} passed in at construction time, if available.
+     * Otherwise, attempt to retrieve a {@code WebApplicationContext} from the
+     * {@code ServletContext} attribute with the {@linkplain #setContextAttribute
+     * configured name} if set. Otherwise look up a {@code WebApplicationContext} under
+     * the well-known "root" application context attribute. The
+     * {@code WebApplicationContext} must have already been loaded and stored in the
+     * {@code ServletContext} before this filter gets initialized (or invoked).
+     * <p>Subclasses may override this method to provide a different
+     * {@code WebApplicationContext} retrieval strategy.
+     * @return the {@code WebApplicationContext} for this proxy, or {@code null} if not found
+     * @see #DelegatingFilterProxy(String, WebApplicationContext)
+     * @see #getContextAttribute()
+     * @see WebApplicationContextUtils#getWebApplicationContext(ServletContext)
+     * @see WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
+     */
+    protected WebApplicationContext findWebApplicationContext() {
+        if (this.webApplicationContext != null) {
+            // The user has injected a context at construction time -> use it...
+            if (this.webApplicationContext instanceof ConfigurableApplicationContext) {
+                ConfigurableApplicationContext cac = (ConfigurableApplicationContext) this.webApplicationContext;
+                if (!cac.isActive()) {
+                    // The context has not yet been refreshed -> do so before returning it...
+                    cac.refresh();
+                }
+            }
+            return this.webApplicationContext;
+        }
+        String attrName = getContextAttribute();
+        if (attrName != null) {
+            return WebApplicationContextUtils.getWebApplicationContext(getServletContext(), attrName);
+        }
+        else {
+            return WebApplicationContextUtils.findWebApplicationContext(getServletContext());
+        }
+    }
+
+    /**
+     * Initialize the Filter delegate, defined as bean the given Spring
+     * application context.
+     * <p>The default implementation fetches the bean from the application context
+     * and calls the standard {@code Filter.init} method on it, passing
+     * in the FilterConfig of this Filter proxy.
+     * @param wac the root application context
+     * @return the initialized delegate Filter
+     * @throws ServletException if thrown by the Filter
+     * @see #getTargetBeanName()
+     * @see #isTargetFilterLifecycle()
+     * @see #getFilterConfig()
+     * @see Filter#init(FilterConfig)
+     */
+    protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
+        Filter delegate = wac.getBean(getTargetBeanName(), Filter.class);
+        if (isTargetFilterLifecycle()) {
+            delegate.init(getFilterConfig());
+        }
+        return delegate;
+    }
+
+    /**
+     * Actually invoke the delegate Filter with the given request and response.
+     * @param delegate the delegate Filter
+     * @param request the current HTTP request
+     * @param response the current HTTP response
+     * @param filterChain the current FilterChain
+     * @throws ServletException if thrown by the Filter
+     * @throws IOException if thrown by the Filter
+     */
+    protected void invokeDelegate(
+            Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain)
+            throws ServletException, IOException {
+
+        delegate.doFilter(request, response, filterChain);
+    }
+
+    /**
+     * Destroy the Filter delegate.
+     * Default implementation simply calls {@code Filter.destroy} on it.
+     * @param delegate the Filter delegate (never {@code null})
+     * @see #isTargetFilterLifecycle()
+     * @see Filter#destroy()
+     */
+    protected void destroyDelegate(Filter delegate) {
+        if (isTargetFilterLifecycle()) {
+            delegate.destroy();
+        }
+    }
+
+}
diff --git a/src/main/webapp/WEB-INF/spring-mvc.xml b/src/main/webapp/WEB-INF/spring-mvc.xml
index 223f060..f4d9967 100644
--- a/src/main/webapp/WEB-INF/spring-mvc.xml
+++ b/src/main/webapp/WEB-INF/spring-mvc.xml
@@ -11,12 +11,13 @@
 	http://www.springframework.org/schema/mvc/spring-mvc.xsd
 	http://www.springframework.org/schema/context
 	http://www.springframework.org/schema/context/spring-context-4.0.xsd
-	http://www.springframework.org/schema/task   
+	http://www.springframework.org/schema/task
 	http://www.springframework.org/schema/task/spring-task-4.0.xsd
 	http://www.springframework.org/schema/util
 	http://www.springframework.org/schema/util/spring-util-2.0.xsd">
 
 	<context:component-scan base-package="com.nanometer.smartlab.api"/>
+	<context:component-scan base-package="com.nanometer.smartlab.controller"/>
 
 	<!-- 静态资源(js、image等)的访问 -->
 	<mvc:default-servlet-handler/>
@@ -51,6 +52,6 @@
 	</bean>
 
 	<mvc:cors>
-		<mvc:mapping path="/**" allowed-origins="*" allow-credentials="true" max-age="1800" allowed-methods="GET,POST,OPTIONS"/>
+		<mvc:mapping path="/**" allowed-origins="*" allow-credentials="true" max-age="1800" allowed-methods="GET,POST"/>
 	</mvc:cors>
-</beans>
\ No newline at end of file
+</beans>
diff --git a/src/main/webapp/WEB-INF/spring-shiro.xml b/src/main/webapp/WEB-INF/spring-shiro.xml
index 65070e9..357bd34 100644
--- a/src/main/webapp/WEB-INF/spring-shiro.xml
+++ b/src/main/webapp/WEB-INF/spring-shiro.xml
@@ -1,10 +1,10 @@
 <?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:util="http://www.springframework.org/schema/util"
+       xmlns:util="http://www.springframework.org/schema/util" xmlns:cache="http://www.springframework.org/schema/cache"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
-       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
+       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
 
     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
 
@@ -60,8 +60,9 @@
     </bean>
 
     <!-- Cache Manager -->
-    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
+    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
         <property name="cacheManager" ref="ehcacheManager"/>
+        <property name="transactionAware" value="true"/>
     </bean>
 
     <!-- 如果有多个ehcacheManager要在bean加上p:shared="true" -->
@@ -69,9 +70,30 @@
         <property name="configLocation" value="WEB-INF/ehcache.xml"/>
     </bean>
 
+    <!-- cache注解,和spring-redis.xml中的只能使用一个 -->
+    <cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
+
+    <bean id="shiroSpringCacheManager" class="com.nanometer.smartlab.realm.ShiroSpringCacheManager">
+        <property name="cacheManager" ref="cacheManager"></property>
+    </bean>
+
     <!--session manager-->
     <bean id="sessionManager"
-          class="org.apache.shiro.web.session.mgt.ServletContainerSessionManager">
+          class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
+        <!-- url上带sessionId 默认为true -->
+        <property name="sessionIdUrlRewritingEnabled" value="false"/>
+        <property name="sessionDAO" ref="sessionDAO"/>
+        <!-- cookie名称 -->
+        <property name="sessionIdCookie.name" value="gasid"/>
+        <!-- cookie生效路径 -->
+        <property name="sessionIdCookie.path" value="/"/>
+    </bean>
+
+    <!-- 会话DAO 用于会话的CRUD -->
+    <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
+        <!-- Session缓存名字,默认就是shiro-activeSessionCache -->
+        <property name="activeSessionsCacheName" value="activeSessionCache"/>
+        <property name="cacheManager" ref="shiroSpringCacheManager"/>
     </bean>
 
     <!--credentialsMatcher 密码加密-->
@@ -82,9 +104,9 @@
     </bean>
 
     <!--自定义 Realm-->
-    <bean id="authorizationRealm" class="com.nanometer.smartlab.realm.AuthorizationRealm">
-        <property name="credentialsMatcher" ref="md5Matcher"/>
-
+    <bean id="authorizationRealm" class="com.nanometer.smartlab.realm.ShiroDbRealm">
+        <constructor-arg index="0" name="cacheManager" ref="shiroSpringCacheManager"/>
+        <constructor-arg index="1" name="matcher" ref="credentialsMatcher"/>
         <!-- 启用身份验证缓存,即缓存AuthenticationInfo信息,默认false -->
         <property name="authenticationCachingEnabled" value="true"/>
         <!-- 缓存AuthenticationInfo信息的缓存名称 -->
@@ -92,12 +114,21 @@
         <!-- 缓存AuthorizationInfo信息的缓存名称 -->
         <property name="authorizationCacheName" value="authorizationCache"/>
     </bean>
+    <!-- 密码错误5次锁定5min -->
+    <bean id="credentialsMatcher" class="com.nanometer.smartlab.realm.RetryLimitCredentialsMatcher">
+        <constructor-arg ref="shiroSpringCacheManager"/>
+        <property name="retryLimitCacheName" value="fivMin"/>
+        <!-- 密码加密 1次md5,增强密码可修改此处 -->
+        <property name="hashAlgorithmName" value="MD5"/>
+        <property name="storedCredentialsHexEncoded" value="true"/>
+        <property name="hashIterations" value="1"/>
+    </bean>
 
     <!-- Security Manager -->
     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
         <property name="realm" ref="authorizationRealm"/>
         <property name="rememberMeManager" ref="rememberMeManager"/>
-        <property name="cacheManager" ref="cacheManager"/>
+        <property name="cacheManager" ref="shiroSpringCacheManager"/>
         <property name="sessionManager" ref="sessionManager"/>
     </bean>
 
diff --git a/src/main/webapp/WEB-INF/test/test.properties b/src/main/webapp/WEB-INF/test/test.properties
index 36ee8bd..15a5f91 100644
--- a/src/main/webapp/WEB-INF/test/test.properties
+++ b/src/main/webapp/WEB-INF/test/test.properties
@@ -2,10 +2,9 @@
 jdbc.username=root
 jdbc.password=GKHY@root20201!
 
-#\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD
 institute.id = 2
 institute.name = \u4E2D\u56FD\u79D1\u5B66\u9662\u82CF\u5DDE\u7EB3\u7C73\u6280\u672F\u4E0E\u7EB3\u7C73\u4EFF\u751F\u7814\u7A76\u6240
-institute.url  = http://sinanoaq.com:8050
+institute.url  = https://sinanoaq.cn:8002
 institute.app.id = wx81a00e3350861b25
 institute.app.secret = c307d394875af2cbbe25e01b9e43dcb2
 alarm.url = http://sinanoaq.com/daping/sendWarnInfo.json
diff --git a/src/main/webapp/index.xhtml b/src/main/webapp/index.xhtml
index 406de33..97bb7eb 100644
--- a/src/main/webapp/index.xhtml
+++ b/src/main/webapp/index.xhtml
@@ -41,15 +41,15 @@
                 <p:panelGrid columns="1" styleClass="content">
                     <p:outputLabel value="原密码"></p:outputLabel>
                     <p:password value="#{userMngController.oriPassword}" maxlength="100"
-                             required="true" requiredMessage="请输入原密码"></p:password>
+                             required="true" requiredMessage="请输入原密码" autocomplete="off"></p:password>
 
                      <p:outputLabel value="新密码(必须是8位以上且包含大小写和特殊字符)"></p:outputLabel>
                      <p:password value="#{userMngController.newPassword}" maxlength="100"
-                             required="true" requiredMessage="请输入新密码"></p:password>
+                             required="true" requiredMessage="请输入新密码" autocomplete="off"></p:password>
 
                     <p:outputLabel value="确认密码"></p:outputLabel>
                              <p:password value="#{userMngController.newPasswordSecond}" maxlength="100"
-                             required="true" requiredMessage="请输入确认密码"></p:password>
+                             required="true" requiredMessage="请输入确认密码" autocomplete="off"></p:password>
                 </p:panelGrid>
                 <p:panel styleClass="btn">
                     <p:commandButton value="修改" actionListener="#{userMngController.updatePasswordAction}"
@@ -68,15 +68,15 @@
                 <p:panelGrid columns="1" styleClass="content">
                     <p:outputLabel value="原密码"></p:outputLabel>
                     <p:password value="#{userMngController.oriPassword}" maxlength="100"
-                                required="true" requiredMessage="请输入原密码"></p:password>
+                                required="true" requiredMessage="请输入原密码" autocomplete="off"></p:password>
 
                     <p:outputLabel value="新密码(必须是8位以上且包含大小写和特殊字符)"></p:outputLabel>
                     <p:password value="#{userMngController.newPassword}" maxlength="100"
-                                required="true" requiredMessage="请输入新密码"></p:password>
+                                required="true" requiredMessage="请输入新密码" autocomplete="off"></p:password>
 
                     <p:outputLabel value="确认密码"></p:outputLabel>
                     <p:password value="#{userMngController.newPasswordSecond}" maxlength="100"
-                                required="true" requiredMessage="请输入确认密码"></p:password>
+                                required="true" requiredMessage="请输入确认密码" autocomplete="off"></p:password>
                 </p:panelGrid>
                 <p:panel styleClass="btn">
                     <p:commandButton value="修改" actionListener="#{userMngController.updatePasswordAction}"
diff --git a/src/main/webapp/login.xhtml b/src/main/webapp/login.xhtml
index 478242c..2d7cdce 100644
--- a/src/main/webapp/login.xhtml
+++ b/src/main/webapp/login.xhtml
@@ -50,7 +50,7 @@
 
 					<div>
 						<p:outputLabel value="密码" styleClass="pwd-label"></p:outputLabel>
-						<p:password value="#{loginController.loginPwd}" required="true" requiredMessage="请输入密码"></p:password>
+						<p:password value="#{loginController.loginPwd}" required="true" requiredMessage="请输入密码" autocomplete="off"></p:password>
 					</div>
 					<p:commandButton value="登录" ajax="false" action="#{loginController.login}" styleClass="save-button"></p:commandButton>
 				</div>
@@ -59,14 +59,8 @@
 	</div>
 
 	<div class="login-footer">
-		<!--<p:graphicImage value="/resources/images/logo2.png"></p:graphicImage>-->
-
 			Copyright © 2017  ${institute.name}
-			<!--<p:commandLink id="nonAjax" src="http:beian.miit.gov.cn/"   ajax="false">
-            <h:outputText value="苏ICP备13012319号-1" />
-            </p:commandLink>-->
 			<a href="http://beian.miit.gov.cn">苏ICP备10220403号-6</a>
-
 	</div>
 </h:body>
 </html>
diff --git a/src/main/webapp/user_mng.xhtml b/src/main/webapp/user_mng.xhtml
index 09ccb1b..b133e54 100644
--- a/src/main/webapp/user_mng.xhtml
+++ b/src/main/webapp/user_mng.xhtml
@@ -187,8 +187,7 @@
 
                 <p:outputLabel value="密码" ></p:outputLabel>
                 <p:password value="#{userMngController.sysUser.password}" maxlength="100"
-                             requiredMessage="请输入密码"
-                            ></p:password>
+                             requiredMessage="请输入密码" autocomplete="off"></p:password>
 
                 <p:outputLabel value="电话"></p:outputLabel>
                 <p:inputText value="#{userMngController.sysUser.phone}" maxlength="30"></p:inputText>

--
Gitblit v1.9.2