SpringBoot整合Shiro实现用户认证
添加依赖 org.apache.shiro shiro-spring 1.4.0
前端测试代码
controller(控制层) @RequestMapping("toLogin") public String toLogin(String userName,String password,Model model){ // 使用shiro 编写登录逻辑 // 1。获取subject Subject subject = SecurityUtils.getSubject(); //2。将参数封装成token UsernamePasswordToken token = new UsernamePasswordToken(userName,password); //3。执行登录 try{ subject.login(token); return "logins"; }catch (UnknownAccountException e){ model.addAttribute("message","用户不存在"); return "login"; }catch (IncorrectCredentialsException e){ model.addAttribute("message","密码错误"); return "login"; } }
ShiroConfig(配置类) @Configuration public class ShiroConfig { /* * 创建 ShiroFilterFactoryBean 对象 * */ @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(){ // 创建过滤器 ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); // 设置安全管理器 shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager()); //添加shiro 内置过滤器 /* * shiro 内置过滤器 ,可以实现权限相关的拦截器 * * 常用的过滤器() * anon:无需认证可以访问 * authc:必须认证才可以访问 * user: 如果使用rememberme的功能可以访问 * perms:该资源必须得到资源权限才可以访问 * role:该资源必须得到角色权限才可以访问 * */ Map filterMap = new LinkedHashMap<>(); // 放过的路径 filterMap.put("/shiroController/index","anon"); filterMap.put("/loginController/toLogin","anon");//key:访问路径 value:过滤级别 //拦截所有 filterMap.put("/**","authc"); //强行跳转的页面 shiroFilterFactoryBean.setLoginUrl("/loginController/login"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap); return shiroFilterFactoryBean; } /* * 创建 DefaultWebSecurityManager 用来管理用户主体的subject * */ @Bean public DefaultWebSecurityManager getDefaultWebSecurityManager(){ DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager(); defaultWebSecurityManager.setRealm(getUserRealm()); return defaultWebSecurityManager; } // 使用哈希算法+盐值加密 需要给盐 和 次数 @Bean public UserRealm getUserRealm(){ UserRealm userRealm = new UserRealm(); userRealm.setCredentialsMatcher(getHashedCredentialsMatcher()); return userRealm; } /* * 设置哈希算法 * */ @Bean public HashedCredentialsMatcher getHashedCredentialsMatcher() { //创建hashedCredentialsMatcher 对象 HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); //指定加密方式 MD4 MD5 SHA-1 SHA-256 SHA-384 SHA-512 hashedCredentialsMatcher.setHashAlgorithmName("md5"); //设置加密次数 必须和UserRealm hashedCredentialsMatcher.setHashIterations(1); //设置加密的编码 true:加密使用的是HEX编码 false:base6编码 hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true); return hashedCredentialsMatcher; } }
UserRealm(认证) public class UserRealm extends AuthorizingRealm { @Autowired private UserServiceI userService; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { /* * 执行授权逻辑 * */ System.out.println("》》》》》执行授权逻辑《《《《《《《"); return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { /* * 执行认证逻辑 * */ System.out.println("》》》》》》》》》执行认证逻辑《《《《《《《《《《"); UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken; //调用数据库进行验证 TbUser user = userService.findUserInfoByUserName(token.getUsername()); // 编写登录认证逻辑 if (!token.getUsername().equals(user.getTbUserName())){ return null; } //判断密码 //假设密码正确,也就是登陆成功后的用户密码,好比将他放入到session中 // 数据库查询出来的密码,shiro自动校验 //加的盐 ByteSource.Util.bytes(user.getTbSalt()) //假设密码正确,也就是登陆成功后的用户名 //盐相当于密钥 //shiro 加密方式 盐+次数 进行哈希加密 // return new SimpleAuthenticationInfo(user,user.getTbUserPwd(), ByteSource.Util.bytes(user.getTbSalt()),user.getTbUserName()); } //8fd2fae312c4e621271ea80088cac3a3 public static void main(String[] args) { String s = ShiroUtils.encryptPassword("MD5", "1234", "c440e502", 1); System.out.println(s); } }
ShiroUtils (随机生成 salt) public class ShiroUtils { /** * 随机生成 salt 需要指定 它的字符串的长度 * * @param len 字符串的长度 * @return salt */ public static String generateSalt(int len) { //一个Byte占两个字节 int byteLen = len >> 1; SecureRandomNumberGenerator secureRandom = new SecureRandomNumberGenerator(); return secureRandom.nextBytes(byteLen).toHex(); } /** * 获取加密后的密码,使用默认hash迭代的次数 1 次 * * @param hashAlgorithm hash算法名称 MD2、MD5、SHA-1、SHA-256、SHA-384、SHA-512、etc。 * @param password 需要加密的密码 * @param salt 盐 * @return 加密后的密码 */ public static String encryptPassword(String hashAlgorithm, String password, String salt) { return encryptPassword(hashAlgorithm, password, salt, 1); } /** * 获取加密后的密码,需要指定 hash迭代的次数 * * @param hashAlgorithm hash算法名称 MD2、MD5、SHA-1、SHA-256、SHA-384、SHA-512、etc。 * @param password 需要加密的密码 * @param salt 盐 * @param hashIterations hash迭代的次数 * @return 加密后的密码 */ public static String encryptPassword(String hashAlgorithm, String password, String salt, int hashIterations) { SimpleHash hash = new SimpleHash(hashAlgorithm, password, salt, hashIterations); return hash.toString(); } public static void main(String[] args) { String s = ShiroUtils.generateSalt(8); System.out.println(s); } }
广告轰炸不管用,员工边哭边下单想去哪儿拍去哪儿拍,我就不信你这个夏天没有被这句广告词轰炸过。在各大写字楼的电梯内充斥着分众传媒的广告,而最引人注目的要数BOSS直聘和铂爵旅拍的洗脑广告,重复,重复,无限的重复,
币安的10亿美元生态投资,还能把BNB币价拉上去吗?今天看到消息。币安宣布,投入10亿美金的基金,扶持币安智能链生态。一半资金投入游戏虚拟现实和金融服务。其他的投入开发者项目,以及人才激励。对于公链来说,打造自己的生态是必须的。不然
驻车空调哪个牌子好,海尔驻车空调成车主好伙伴长途驾车对卡车司机们来说无疑是严峻的挑战,他们除了要全神贯注地观察路况外,还要保持充沛的体力,在这样的情形下打造良好车内环境,以便于更好地休息就显得尤为重要了,这也是越来越多的卡车
闲谈加密货币的历史理想和现实(二)面对比特币和其他各类有志于成为市场通用货币的币种而言,管理货币发行的各国央行,也会面临挑战。针对这种挑战,不同国家的发展思路是有差异的。对美国而言,美元本来就是世界储备货币,现在出
闲谈加密货币的历史理想和现实今天看了2篇文章,一篇是一家机构研究中国的虚拟货币的监管政策的,另外一篇是讲到加密货币技术对整个世界货币体系金融体系带来的重大挑战。有感而发,随便讲讲自己的一些看法。2018年,中
Python入门题049比较字符串(忽略大小写)题目比较2个字符串是否相等,忽略字母的大小写。进阶题如何让法语的和ss相等。python大小写敏感str。lower()str。casefold()视频教程Python入门题049
商业项目中改用中文命名标识符实例分析2020年注定难过,说起来并不是改用中文命名的最好时机,因为在压力之下会更倾向于减小风险,包括用老的英文命名方式。另一角度说,如果过渡顺利,在这关键时刻,中文命名标识符这一看似不起
Gitee开源指北1。0开源项目必须用英文命名标识符吗?编者按此部分在整个开源指北1。0文档中,仅占了极小一部分,但其意义不言而喻。初稿起草于2020年10月末,之后颇有波折,包括一次长达一周的pr讨论。很高兴看到此部分在正式发布的此版
紫藤花开,砂石电商1。29万亿元水利工程大项目来了前言2020年至2022年将推进150项重大水利工程建设,主要包括防洪减灾水资源优化配置灌溉节水和供水水生态保护修复智慧水利等五大类,总投资1。29万亿元。近日召开的国务院常务会议
美国政界对大科技公司垄断感到恐惧开6小时听证会拷问CEO该来的总会来的,美国政界对于科技巨头的逐渐壮大并没有为此而感觉自豪,反倒是害怕起来了。近两年来,拆分这些科技巨头,或者把科技巨头与垄断关联起来已经成为一个并不小众的话题。这些大科技
2021砂石刚需不减!2021年计划开工铁路项目汇总中国国铁集团最新统计,截止2020年底,全国建成京雄城际铁路银西高铁郑太高铁合安高铁连淮扬镇高铁沪苏通铁路潍莱高铁等在内的29条铁路新线顺利开通运营,累计投产营运里程超过4800公