摘要:项目介绍在之前的整合项目之后,更加完善功能,之前的代码不予展示与介绍,想了解的请参考整合项目项目代码获取功能新增用户注册登录错误次数限制使用作缓存注解配置引入数据校验使用统一异常处理配置项目结构代码控制层,以下展示注册和登录功能会跳到我们自
shiro项目介绍
在之前的shiro整合项目之后,更加完善shiro功能,之前的代码不予展示与介绍,想了解的请参考shiro整合项目
项目代码获取:https://github.com/pysasuke/s...
用户注册
登录错误次数限制(使用redis作缓存)
shiro注解配置
DTO引入
数据校验(使用hibernate validation)
SpringMVC统一异常处理配置
项目结构 java:代码controller:控制层,以下展示注册和登录功能
@RequestMapping("/login") public String login(ShiroUser shiroUser, HttpServletRequest request) { Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(shiroUser.getUsername(), shiroUser.getPassword()); try { subject.login(token);//会跳到我们自定义的realm中 request.getSession().setAttribute("user", shiroUser); log.info(shiroUser.getUsername() + "登录"); return "user/success"; } catch (UnknownAccountException e) { return "user/login"; } catch (IncorrectCredentialsException e) { request.setAttribute("error", "用户名或密码错误"); return "user/login"; } catch (ExcessiveAttemptsException e) { request.setAttribute("error", "输入密码错误太多次,请稍后再试!"); return "user/login"; } catch (Exception e) { request.setAttribute("error", "未知错误"); return "user/login"; } } @RequestMapping(value = "/register", method = RequestMethod.POST) public String register(Model model, @Valid @ModelAttribute ShiroUserDTO shiroUserDTO, BindingResult bindingResult) { //数据校验 if (bindingResult.hasErrors()) { ListallErrors = bindingResult.getAllErrors(); for (ObjectError objectError : allErrors) { //输出错误信息 System.out.println(objectError.getDefaultMessage()); } model.addAttribute("error", "填入信息有误"); model.addAttribute("user", shiroUserDTO); return "/user/register"; } if (shiroUserService.getByUsername(shiroUserDTO.getUsername()) == null) { shiroUserService.insertUser(shiroUserDTO); return "redirect:/"; } else { model.addAttribute("user", shiroUserDTO); model.addAttribute("error", "userName has been registered!"); return "/user/register"; } }
service:业务处理层,以下展示新增用户功能,包含数据转换(DTO到Entity)和密码加密(shiro加密策略)
public void insertUser(ShiroUserDTO shiroUserDTO) { ShiroUser shiroUser = converToAddress(shiroUserDTO); shiroUserMapper.insert(shiroUser); } private ShiroUser converToAddress(ShiroUserDTO shiroUserDTO) { ShiroUser shiroUser = new ShiroUser(); BeanUtils.copyProperties(shiroUserDTO, shiroUser); passwordEncrypt(shiroUser); shiroUser.setCreatetime(new Date()); shiroUser.setRoleId(1); return shiroUser; } private void passwordEncrypt(ShiroUser shiroUser) { String username = shiroUser.getUsername(); String password = shiroUser.getPassword(); String salt2 = new SecureRandomNumberGenerator().nextBytes().toHex(); int hashIterations = 3; String algorithmName = "md5"; SimpleHash hash = new SimpleHash(algorithmName, password, username + salt2, hashIterations); String encodedPassword = hash.toHex(); shiroUser.setSalt(salt2); shiroUser.setPassword(encodedPassword); }
dao:数据库交互层
entity:实体对象层,以下展示数据校验
@Data public class ShiroUser { private Integer id; @NotNull(message = "用户名不能为空") @Size(min = 3, max = 16, message = "用户名长度必须介于3-16个字符之间") private String username; @NotNull(message = "密码不能为空") @Size(min = 3, max = 16, message = "{密码长度必须介于3-16个字符之间") private String password; private Date createtime; private Date lasttime; @Email(message = "请输入正确的邮箱") private String email; private String sex; private String salt; private Integer roleId; }
realm:自定义Realm(shiro相关),以下加入了加密相关代码
public class MyRealm extends AuthorizingRealm { @Resource private ShiroUserService shiroUserService; // 为当前登陆成功的用户授予权限和角色,已经登陆成功了 @Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { String username = (String) principals.getPrimaryPrincipal(); //获取用户名 SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); authorizationInfo.setRoles(shiroUserService.getRoles(username)); authorizationInfo.setStringPermissions(shiroUserService.getPermissions(username)); return authorizationInfo; } // 验证当前登录的用户,获取认证信息 @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { String username = (String) token.getPrincipal(); // 获取用户名 ShiroUser shiroUser = shiroUserService.getByUsername(username); if (shiroUser != null) { SimpleAuthenticationInfo authcInfo = new SimpleAuthenticationInfo(shiroUser.getUsername(), shiroUser.getPassword(), "myRealm"); //通过SimpleAuthenticationInfo的credentialsSalt设置盐,HashedCredentialsMatcher会自动识别这个盐。 authcInfo.setCredentialsSalt(ByteSource.Util.bytes(shiroUser.getUsername() + shiroUser.getSalt())); return authcInfo; } else { return null; } } }
constants:常量类包
dto:DTO对象包,以下展示ShiroUserDTO(只包含交互相关的字段)
@Data public class ShiroUserDTO { @NotNull(message = "用户名不能为空") @Size(min = 3, max = 16, message = "用户名长度必须介于3-16个字符之间") private String username; @NotNull(message = "密码不能为空") @Size(min = 3, max = 16, message = "{密码长度必须介于3-16个字符之间") private String password; @Email(message = "请输入正确的邮箱") private String email; @NotNull(message = "请选择性别") private String sex; }
credentials:处理重试次数类包
public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher { @Autowired private RedisCache redisCache; //匹配用户输入的token的凭证(未加密)与系统提供的凭证(已加密) @Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { String username = (String) token.getPrincipal(); //retry count + 1 //AtomicInteger是一个提供原子操作的Integer类,通过线程安全的方式操作加减。 AtomicInteger retryCount = redisCache.getCache(Constants.USER + username, AtomicInteger.class); if (retryCount == null) { retryCount = new AtomicInteger(0); } //增长 if (retryCount.incrementAndGet() > 5) { //if retry count > 5 throw throw new ExcessiveAttemptsException(); } redisCache.putCacheWithExpireTime(Constants.USER + username, retryCount, 600); boolean matches = super.doCredentialsMatch(token, info); if (matches) { //clear retry count redisCache.deleteCache(Constants.USER + username); } return matches; } }resources:配置文件
application.xml:spring配置文件入口,加载spring-config.xml
spring-mvc.xml:springmvc配置相关文件
spring-config.xml:加载其他集成的配置文件,这里加载spring-mybatis.xml、spring-shiro.xml和db.properties
spring-mybatis.xml:mybatis相关配置文件
spring-shiro.xml:shiro配置相关文件
redirect:/user/login redirect:/user/login
db.properties:数据库相关参数配置
log4j.properties:日志相关参数配置
mapping:存放mybatis映射文件,以UserMapper.xml为例
redis.properties:redis相关参数配置
#redis config redis.pool.maxTotal=100 redis.pool.maxIdle=10 redis.pool.maxWaitMillis=5000 redis.pool.testOnBorrow=true redis.pool.maxActive= 100 redis.pool.maxWait= 3000 #redis ip和端口号 redis.ip=127.0.0.1 redis.port=6379 redis.pass=
spring-redis.xml:redis相关配置
spring-mvc-shiro.xml:shiro注解相关配置
webapp:web相关
web.xml
其他文件 logs:日志存放 deploy:部署文件(sql)shiroFilter org.springframework.web.filter.DelegatingFilterProxy targetFilterLifecycle true shiroFilter /*
update.sql
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `t_permission` -- ---------------------------- DROP TABLE IF EXISTS `t_permission`; CREATE TABLE `t_permission` ( `id` int(11) NOT NULL, `role_id` int(11) NOT NULL, `permissionname` varchar(100) COLLATE utf8mb4_bin NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; -- ---------------------------- -- Records of t_permission -- ---------------------------- INSERT INTO `t_permission` VALUES ("1", "1", "user:create"); INSERT INTO `t_permission` VALUES ("2", "2", "user:update"); INSERT INTO `t_permission` VALUES ("3", "1", "user:update"); -- ---------------------------- -- Table structure for `t_role` -- ---------------------------- DROP TABLE IF EXISTS `t_role`; CREATE TABLE `t_role` ( `id` int(11) NOT NULL AUTO_INCREMENT, `rolename` varchar(20) COLLATE utf8mb4_bin NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; -- ---------------------------- -- Records of t_role -- ---------------------------- INSERT INTO `t_role` VALUES ("1", "teacher"); INSERT INTO `t_role` VALUES ("2", "student"); -- ---------------------------- -- Table structure for `t_user` -- ---------------------------- DROP TABLE IF EXISTS `t_user`; CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userName` varchar(20) NOT NULL, `password` varchar(50) NOT NULL, `createTime` date DEFAULT NULL, `lastTime` datetime DEFAULT NULL, `email` varchar(256) DEFAULT NULL, `sex` enum("male","female") DEFAULT "male", `salt` varchar(50) DEFAULT NULL, `role_id` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of t_user -- ---------------------------- INSERT INTO `t_user` VALUES ("1", "admin", "86c4604b628d4e91f5f2a2fed3f88430", "2017-08-28", null, "404158848@qq.com", "male", "26753209835f4c837066d1cc7d9b46aa", "1"); INSERT INTO `t_user` VALUES ("2", "test", "a038892c7b638aad0357adb52cabfb29", "2017-08-28", null, "404158848@qq.com", "male", "6ced07d939407fb0449d92d9f17cfcd1", "2"); INSERT INTO `t_user` VALUES ("3", "test1", "4be958cccb89213221888f9ffca6969b", "2017-08-28", null, "404158848@qq.com", "male", "c95a278e52daf5166b1ffd6436cde7b7", "1");pom.xml:maven相关
redis.clients jedis 2.8.0 org.springframework.data spring-data-redis 1.6.4.RELEASE com.dyuproject.protostuff protostuff-core 1.0.8 com.dyuproject.protostuff protostuff-runtime 1.0.8 org.hibernate hibernate-validator 5.0.2.Final
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/70330.html
摘要:大家好,今天给大家分享一个权限管理的框架的,说实话本来我是准备看的,毕竟是家族的框架,和整合更加容易一些。官方给出的介绍是是一个强大且易用的安全框架执行身份验证授权密码学和会话管理。由此可知,的主要功能是认证授权加密密和会话管理。 showImg(https://segmentfault.com/img/bV1BsT?w=1726&h=256); 大家好,今天给大家分享一个权限管理的框...
摘要:大家好,今天给大家分享一个权限管理的框架的,说实话本来我是准备看的,毕竟是家族的框架,和整合更加容易一些。官方给出的介绍是是一个强大且易用的安全框架执行身份验证授权密码学和会话管理。由此可知,的主要功能是认证授权加密密和会话管理。 showImg(https://segmentfault.com/img/bV1BsT?w=1726&h=256); 大家好,今天给大家分享一个权限管理的框...
摘要:项目介绍在之前的整合项目之后,新增日志简单集成,之前的代码不予展示与介绍,想了解的请参考整合项目项目代码获取项目结构代码控制层,,主要包含登录及几个页面跳转会跳到我们自定义的中登录用户名或密码错误业务处理层,包含一个包,以接口类型存在 spring-springmvc-mybatis-shiro项目介绍 在之前的mybatis整合项目之后,新增日志、简单集成shiro,之前的代码不予展...
摘要:的统一认证授权是下面的一个简单,易用的权限框架,对于单体应用来讲,完全能够极好的,快速的满足权限的需求,所以一般在做项目的时候,都会成为开发者的首选。 Shiro的统一认证授权 Shiro是Apache下面的一个简单,易用的Java权限框架,对于单体应用来讲,Shiro完全能够极好的,快速的满足权限的需求,所以一般在做项目的时候,Shiro都会成为开发者的首选。 可是,如果你需要做第二...
摘要:是什么是功能强大简单易用的安全框架,核心功能包括认证授权加密以及管理。的主要作用就是用来执行认证和授权的逻辑,它其实就相当于与安全数据用户账号密码角色权限之间进行交互的桥梁。至此,的三个核心概念已经介绍完毕。 1、Shiro是什么 Shiro是功能强大、简单易用的Java安全框架,核心功能包括:认证、授权、加密以及Session管理。Shiro的应用范围很广泛,小型移动端应用、大型We...
阅读 1549·2021-10-18 13:35
阅读 2327·2021-10-09 09:44
阅读 746·2021-10-08 10:05
阅读 2670·2021-09-26 09:47
阅读 3515·2021-09-22 15:22
阅读 399·2019-08-29 12:24
阅读 1913·2019-08-29 11:06
阅读 2826·2019-08-26 12:23