diff --git a/dem b/dem new file mode 100644 index 0000000..e69de29 diff --git a/demo-shiro-interface/src/main/java/com/xinwei/utils/Constants.java b/demo-shiro-interface/src/main/java/com/xinwei/utils/Constants.java index a7fb3b6..2ababa5 100644 --- a/demo-shiro-interface/src/main/java/com/xinwei/utils/Constants.java +++ b/demo-shiro-interface/src/main/java/com/xinwei/utils/Constants.java @@ -7,9 +7,7 @@ import java.util.Map; public class Constants { - /** - * 企业用户需要审核才能登陆,非企业用户默认审核成功 - */ + public static String userStatus_0="0";//注册用户未审核 public static String userStatus_1="1";//注册用户已审核 public static String userStatus_2="2";//注册用户被锁定 @@ -31,65 +29,7 @@ public class Constants { */ public final static String REDIS_SHIRO_SESSION = "shiro-session:"; /*****************************************shiro redis 管理设置 end*********************************************************/ - - - /*****************************************报表导出 start*********************************************************/ - public static List list1 =new ArrayList(); - public static List list2 =new ArrayList(); - public static Map map=new HashMap(); - public static Map mapValue=new HashMap(); - - static{ - - list1.add("与工业控制系统网络相连的网络"); - list1.add("连接方式"); - list1.add("连接时间"); - list1.add("连接后身份认证方式"); - list1.add("连接管理制度"); - list1.add("合法系统间互联的识别和认证技术措施"); - - - list2.add("移动存储介质使用管理制度"); - list2.add("系统网络和公共网之间交叉使用移动存储介质"); - list2.add("工业控制系统主机的存储介质使用情况检查"); - list2.add("移动存储介质自动播放功能"); - list2.add("工业控制系统与其他系统之间专用的安全信息交换途径"); - list2.add("移动存储介质销毁处置流程"); - - - - - map.put("工业控制系统网络与公共网络的连接管理",list1); - map.put("存储介质使用管理",list2); - - - - mapValue.put("与工业控制系统网络相连的网络", "内部局域网-互联网-企业管理网-其他网络-无连接"); - mapValue.put("连接方式","直接相连-采取隔离措施后连接-防火墙"); - mapValue.put("连接时间","始终连接-有需要时连接-无连接"); - mapValue.put("连接后身份认证方式","口令-数字认证技术-无认证"); - mapValue.put("连接管理制度","审批备案-定期检查-风险评估-隔离措施有效性验证-无"); - mapValue.put("合法系统间互联的识别和认证技术措施","有-无"); - - mapValue.put("移动存储介质使用管理制度","有-无"); - mapValue.put("系统网络和公共网之间交叉使用移动存储介质","禁止-未禁止-未要求"); - mapValue.put("工业控制系统主机的存储介质使用情况检查","定期-不定期-不检查"); - mapValue.put("移动存储介质自动播放功能","明文禁止-未禁止-未要求"); - mapValue.put("工业控制系统与其他系统之间专用的安全信息交换途径","有-无"); - mapValue.put("移动存储介质销毁处置流程","有-无"); - - - - - } - - - - - /*****************************************报表导出 end*********************************************************/ - - diff --git a/demo-shiro-web/pom.xml b/demo-shiro-web/pom.xml index a39ae47..e8f96b1 100644 --- a/demo-shiro-web/pom.xml +++ b/demo-shiro-web/pom.xml @@ -16,7 +16,6 @@ demo.xinwin demo-shiro-service 1.0-SNAPSHOT - org.springframework.boot diff --git a/demo-shiro-web/src/main/java/com/xinwei/common/RedisConfig.java b/demo-shiro-web/src/main/java/com/xinwei/common/RedisConfig.java index 369325b..d015ed6 100644 --- a/demo-shiro-web/src/main/java/com/xinwei/common/RedisConfig.java +++ b/demo-shiro-web/src/main/java/com/xinwei/common/RedisConfig.java @@ -66,5 +66,13 @@ public class RedisConfig extends CachingConfigurerSupport { template.setKeySerializer(new StringRedisSerializer()); return template; } + + + + + + + + } \ No newline at end of file diff --git a/demo-shiro-web/src/main/java/com/xinwei/control/UserController.java b/demo-shiro-web/src/main/java/com/xinwei/control/UserController.java index b8851c5..bef172a 100644 --- a/demo-shiro-web/src/main/java/com/xinwei/control/UserController.java +++ b/demo-shiro-web/src/main/java/com/xinwei/control/UserController.java @@ -32,7 +32,10 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * Shiro测试Controller @@ -521,6 +524,7 @@ public class UserController { // token.setRememberMe(true); // 获取当前的Subject Subject currentUser = SecurityUtils.getSubject(); + try { // 在调用了login方法后,SecurityManager会收到AuthenticationToken,并将其发送给已配置的Realm执行必须的认证检查 @@ -528,6 +532,7 @@ public class UserController { // 所以这一步在调用login(token)方法时,它会走到MyRealm.doGetAuthenticationInfo()方法中,具体验证方式详见此方法 logger.info("对用户[" + username + "]进行登录验证..验证开始"); currentUser.login(token); + logger.info("对用户[" + username + "]进行登录验证..验证通过"); //begin 添加记录日志功能 @@ -602,24 +607,6 @@ public class UserController { } - // - // public Cookie getCookie(String cName,HttpServletRequest request) throws - // Exception - // { - // Cookie cookie=null; - // Cookie[] cs=this.getRequest().getCookies(); - // if(cs!=null) - // { - // for(Cookie c:cs) - // { - // String name=c.getName(); - // if(cName.equals(name)) - // { - // cookie=c; - // } - // } - // } - // return cookie; - // } + } \ No newline at end of file diff --git a/demo-shiro-web/src/main/java/com/xinwei/shiro/JedisShiroSessionRepository.java b/demo-shiro-web/src/main/java/com/xinwei/shiro/JedisShiroSessionRepository.java index 1799cd4..8045335 100644 --- a/demo-shiro-web/src/main/java/com/xinwei/shiro/JedisShiroSessionRepository.java +++ b/demo-shiro-web/src/main/java/com/xinwei/shiro/JedisShiroSessionRepository.java @@ -19,8 +19,6 @@ public class JedisShiroSessionRepository implements ShiroSessionRepository { private static Logger logger = LoggerFactory.getLogger(JedisShiroSessionRepository.class); private RedisTemplate objectRedisTemplate; - // @Autowired - // RedisTemplate redisTemplate; @Override public void saveSession(Session session) { diff --git a/demo-shiro-web/src/main/java/com/xinwei/shiro/MyShiroRealm.java b/demo-shiro-web/src/main/java/com/xinwei/shiro/MyShiroRealm.java index cdbea68..e333056 100644 --- a/demo-shiro-web/src/main/java/com/xinwei/shiro/MyShiroRealm.java +++ b/demo-shiro-web/src/main/java/com/xinwei/shiro/MyShiroRealm.java @@ -46,8 +46,7 @@ public class MyShiroRealm extends AuthorizingRealm{ /** * 权限认证,为当前登录的Subject授予角色和权限 * @see:本例中该方法的调用时机为需授权资源被访问时 - * @see :并且每次访问需授权资源时都会执行该方法中的逻辑,这表明本例中默认并未启用AuthorizationCache - * @see :如果连续访问同一个URL(比如刷新),该方法不会被重复调用,Shiro有一个时间间隔(也就是cache时间,在ehcache-shiro.xml中配置),超过这个时间间隔再刷新页面,该方法会被执行 + * @see :如果连续访问同一个URL(比如刷新),该方法不会被重复调用,Shiro有一个时间间隔(系统提供三种cache:内存,ehcache ,redis,在ehcache-shiro.xml中配置),超过这个时间间隔再刷新页面,该方法会被执行 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { @@ -65,13 +64,13 @@ public class MyShiroRealm extends AuthorizingRealm{ List roleList=user.getRoleList(); for (ShiroRole role : roleList) { info.addStringPermissions(role.getPermissionsName()); + // 或者按下面这样添加 + // 添加一个角色,不是配置意义上的添加,而是证明该用户拥有admin角色 + // info.addRole(role.getRoleName()); + //添加权限 + // info.addStringPermission("admin:manage"); } - // 或者按下面这样添加 - // 添加一个角色,不是配置意义上的添加,而是证明该用户拥有admin角色 - // info.addRole("admin"); - //添加权限 - // info.addStringPermission("admin:manage"); - logger.info("已为用户[mike]赋予了[admin]角色和[admin:manage]权限"); + return info; } // 返回null的话,就会导致任何用户访问被拦截的请求时,都会自动跳转到unauthorizedUrl指定的地址 diff --git a/demo-shiro-web/src/main/java/com/xinwei/shiro/RedisCache.java b/demo-shiro-web/src/main/java/com/xinwei/shiro/RedisCache.java new file mode 100644 index 0000000..04f0b79 --- /dev/null +++ b/demo-shiro-web/src/main/java/com/xinwei/shiro/RedisCache.java @@ -0,0 +1,97 @@ +package com.xinwei.shiro; +import java.util.Collection; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.apache.shiro.cache.Cache; +import org.apache.shiro.cache.CacheException; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.util.SerializationUtils; + +import com.xinwei.utils.Constants; + + +public class RedisCache implements Cache { + + private long expireTime = 120;// 缓存的超时时间,单位为s + private String name; + private RedisTemplate redisTemplate;// 通过构造方法注入该对象 + // private RedisTemplate redisTemplate;// 通过构造方法注入该对象 + + public RedisCache() { + super(); + } + + public RedisCache(long expireTime, RedisTemplate redisTemplate,String name) { + super(); + this.expireTime = expireTime; + this.redisTemplate = redisTemplate; + this.name=name; + } + + /** + * 通过key来获取对应的缓存对象 + * 通过源码我们可以发现,shiro需要的key的类型为Object,V的类型为AuthorizationInfo对象 + */ + @Override + public V get(K key) throws CacheException { + //return redisTemplate.opsForValue().get(key); + V obj =redisTemplate.opsForValue().get(name+new String(SerializationUtils.serialize(getCacheKey(key)))); + if(obj!=null) + { + System.out.println(obj.toString()); + } + return obj; + } + + /** + * 将权限信息加入缓存中 + */ + @Override + public V put(K key, V value) throws CacheException { + + // redisTemplate.opsForValue().set(key, value, this.expireTime, TimeUnit.SECONDS); + redisTemplate.opsForValue().set(name+new String(SerializationUtils.serialize(getCacheKey(key))), value, this.expireTime, TimeUnit.SECONDS); + return value; + } + + /** + * 将权限信息从缓存中删除 + */ + @Override + public V remove(K key) throws CacheException { + // V v = redisTemplate.opsForValue().get(key); + // redisTemplate.opsForValue().getOperations().delete(key); + + V v = redisTemplate.opsForValue().get(name+new String(SerializationUtils.serialize(getCacheKey(key)))); + redisTemplate.opsForValue().getOperations().delete(name+new String(SerializationUtils.serialize(getCacheKey(key)))); + + System.out.println("====removeremove========="+key+"==============="); + return v; + } + + @Override + public void clear() throws CacheException { + System.out.println("clearclearclearclearclearclearclearclearclear"); + } + + @Override + public int size() { + return 0; + } + + @Override + public Set keys() { + return null; + } + + @Override + public Collection values() { + return null; + } + + private String getCacheKey(Object key) { + return Constants.REDIS_SHIRO_CACHE + ":" + key; + } + +} \ No newline at end of file diff --git a/demo-shiro-web/src/main/java/com/xinwei/shiro/RedisCacheManager.java b/demo-shiro-web/src/main/java/com/xinwei/shiro/RedisCacheManager.java new file mode 100644 index 0000000..6f3b284 --- /dev/null +++ b/demo-shiro-web/src/main/java/com/xinwei/shiro/RedisCacheManager.java @@ -0,0 +1,48 @@ +package com.xinwei.shiro; + +import org.apache.shiro.cache.Cache; +import org.apache.shiro.cache.CacheException; +import org.apache.shiro.cache.CacheManager; +import org.apache.shiro.util.Destroyable; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; + +import com.xinwei.spring.boot.autoconfigure.shiro.ShiroProperties; + +/** +* @desc 该类提供redis cache。缓存 登录失败次数和用户权限。 + * 过期时间分别对应application.yml 中的 + * retry-expire-time-redis +* authorization-expire-time-redis +* @author wangxinwei +* @date 2018-02-07 04:23 +*/ +public class RedisCacheManager implements CacheManager, Destroyable { + + + private RedisTemplate redisTemplate; + private long expireTime; + + @Autowired + private ShiroProperties properties; + + public RedisCacheManager(RedisTemplate redisTemplateTemp){ + redisTemplate = redisTemplateTemp; + } + @Override + public Cache getCache(String name) throws CacheException { + + if(name.equals("passwordRetryCache")){ + expireTime = properties.getRetryExpireTimeRedis(); + }else{ + expireTime = properties.getAuthorizationExpireTimeRedis(); + } + return new RedisCache(expireTime, redisTemplate,name);// 为了简化代码的编写,此处直接new一个Cache + } + + @Override + public void destroy() throws Exception { + + } + +} \ No newline at end of file diff --git a/demo-shiro-web/src/main/java/com/xinwei/shiro/ShiroConfiguration.java b/demo-shiro-web/src/main/java/com/xinwei/shiro/ShiroConfiguration.java index 334f698..5777130 100644 --- a/demo-shiro-web/src/main/java/com/xinwei/shiro/ShiroConfiguration.java +++ b/demo-shiro-web/src/main/java/com/xinwei/shiro/ShiroConfiguration.java @@ -1,16 +1,31 @@ package com.xinwei.shiro; +import org.apache.shiro.cache.CacheManager; +import org.apache.shiro.cache.MemoryConstrainedCacheManager; +import org.apache.shiro.cache.ehcache.EhCacheManager; import org.apache.shiro.session.mgt.eis.SessionDAO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import org.springframework.data.redis.core.RedisTemplate; +import com.xinwei.spring.boot.autoconfigure.shiro.ShiroProperties; + + @Configuration public class ShiroConfiguration { + @Autowired + public ShiroProperties properties; + + /** + * * 注释掉该方法时 ,shiro的登录会话session由ehcache保持。 * 打开该方法时,shiro的登录回话session由redis保持。 * @param jedisShiroSessionRepository @@ -23,7 +38,9 @@ public class ShiroConfiguration { customShiroSessionDAO.setShiroSessionRepository(jedisShiroSessionRepository); return customShiroSessionDAO; } - + + + @Bean @DependsOn(value = { "objectRedisTemplate" }) public JedisShiroSessionRepository jedisShiroSessionRepository(RedisTemplate objectRedisTemplate) { @@ -33,5 +50,45 @@ public class ShiroConfiguration { } + /** + * (基于内存的)用户授权信息Cache + */ + @Bean(name = "shiroCacheManager") + @ConditionalOnMissingBean(name = "shiroCacheManager") + // @ConditionalOnMissingClass(value = {"org.apache.shiro.cache.ehcache.EhCacheManager"}) + public CacheManager memoryCacheManager() { + + return new MemoryConstrainedCacheManager(); + } + + + /** + * (基于redis的)用户授权信息Cache + */ + @Bean(name = "shiroCacheManager") + @ConditionalOnMissingBean(name="shiroCacheManager") + public CacheManager redisCacheManager(RedisTemplate redisTemplate) { + + return new RedisCacheManager(redisTemplate); + } + + /** + * (基于ehcache的)用户授权信息Cache + */ + @Bean(name = "shiroCacheManager") + @ConditionalOnClass(name = {"org.apache.shiro.cache.ehcache.EhCacheManager"}) + @ConditionalOnMissingBean(name = "shiroCacheManager") + public CacheManager ehcacheCacheManager() { + EhCacheManager ehCacheManager = new EhCacheManager(); + ShiroProperties.Ehcache ehcache = properties.getEhcache(); + if (ehcache.getCacheManagerConfigFile() != null) { + ehCacheManager.setCacheManagerConfigFile(ehcache.getCacheManagerConfigFile()); + } + return ehCacheManager; + } + + + + } \ No newline at end of file diff --git a/demo-shiro-web/src/main/resources/application.yml b/demo-shiro-web/src/main/resources/application.yml index c3aaebc..71a8556 100644 --- a/demo-shiro-web/src/main/resources/application.yml +++ b/demo-shiro-web/src/main/resources/application.yml @@ -3,12 +3,9 @@ shiro: custom-authc-filter-class: com.xinwei.shiro.AjaxAuthorizationFilter login-url: /login success-url: /admin/sysFunctionManager/role_manager - unauthorized-url: /403 - retry-max: 10000 - sign-in: - user-param: username - password-param: password - remember-me-param: rememberMe + retry-max: 5 + retry-expire-time-redis: 5 + authorization-expire-time-redis: 10 hash-iterations: 1024 hash-algorithm-name: MD5 stored-credentials-hex-encoded: false @@ -18,6 +15,5 @@ shiro: validation-scheduler-enabled: true filter-chain-definitions: /media/**: anon - /user/edit/*: authc,perms[user:edit] /admin/**: authc - \ No newline at end of file + diff --git a/demo-shiro-web/src/main/resources/ehcache.xml b/demo-shiro-web/src/main/resources/ehcache.xml new file mode 100755 index 0000000..19a099d --- /dev/null +++ b/demo-shiro-web/src/main/resources/ehcache.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + diff --git a/demo-shiro-web/src/main/resources/log4j.properties b/demo-shiro-web/src/main/resources/log4j.properties index 05a15e4..2e0689b 100644 --- a/demo-shiro-web/src/main/resources/log4j.properties +++ b/demo-shiro-web/src/main/resources/log4j.properties @@ -1,4 +1,4 @@ -log4j.rootLogger=INFO, console +log4j.rootLogger=DEBUG, console #log4j.rootLogger=INFO, console, file log4j.appender.console=org.apache.log4j.ConsoleAppender diff --git a/demo-shiro-web/src/main/resources/static/media/js/table-managed.js b/demo-shiro-web/src/main/resources/static/media/js/table-managed.js index 04a5cca..3e47b3c 100644 --- a/demo-shiro-web/src/main/resources/static/media/js/table-managed.js +++ b/demo-shiro-web/src/main/resources/static/media/js/table-managed.js @@ -89,21 +89,7 @@ var TableManaged = function () { // datatable.reload(null, false); }); - $("#editUser").on('click',function(){ - var arr= setSelectAll(); - if(arr[0]>1){ - - appcommon.alert("每次只能修改一条记录",0,2000); - return; - } - - if(arr[0]==0){ - appcommon.alert("请选择记录",0,2000); - return ; - } - toEditUserPage(arr[1]); - }); $("#delUser").on('click',function(){ var arr = setSelectAll(); @@ -340,36 +326,7 @@ function addUserSubmit(){ }); } -/** - * 获取待修改用户的值 - */ -function toEditUserPage(username){ - $.ajax({ - url:'/admin/toEditUserPage', - type:'post', - data:'username='+username, - async : true,// 默认为true 异步 - error:function(){ - - appcommon.alert("系统异常",2); - }, - success:function(data){ - var data = $.parseJSON(data); - - $("#editUser-form input[name=company]").val(data.company); - $("#editUser-form input[name=email]").val(data.email); - $("#editUser-form input[name=position]").val(data.position); - $("#editUser-form input[name=fax]").val(data.fax); - $("#editUser-form input[name=mobile]").val(data.mobile); - $("#editUser-form input[name=realName]").val(data.realName); - $("#editUser-form input[name=username1]").val(data.username); - $("#editUser-form input[name=username]").val(data.username); - $('#Modal-EditUser').modal('show') - - TableManaged.editUserValidator(); - } - }); -} + /** diff --git a/demo-shiro-web/src/main/resources/templates/admin/addUser.ftl b/demo-shiro-web/src/main/resources/templates/admin/addUser.ftl index 82ffae3..73a0950 100644 --- a/demo-shiro-web/src/main/resources/templates/admin/addUser.ftl +++ b/demo-shiro-web/src/main/resources/templates/admin/addUser.ftl @@ -20,80 +20,9 @@ -
- -
-
- -
- -
-
-
-
-
- -
-
- -
- -
-
-
-
-
- -
-
- -
- -
- -
-
-
- -
- -
-
- -
- -
- -
-
-
-
- -
-
- -
- -
- -
-
-
-
- -
-
- -
- -
- -
-
-