摘要:項目介紹在之前的整合項目之后,更加完善功能,之前的代碼不予展示與介紹,想了解的請參考整合項目項目代碼獲取功能新增用戶注冊登錄錯誤次數限制使用作緩存注解配置引入數據校驗使用統一異常處理配置項目結構代碼控制層,以下展示注冊和登錄功能會跳到我們自
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
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/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...
閱讀 1579·2021-10-18 13:35
閱讀 2359·2021-10-09 09:44
閱讀 813·2021-10-08 10:05
閱讀 2707·2021-09-26 09:47
閱讀 3560·2021-09-22 15:22
閱讀 427·2019-08-29 12:24
閱讀 1993·2019-08-29 11:06
閱讀 2853·2019-08-26 12:23