关于登录-Sha256Hash+salt 秘密 jwt Token
登录有很多种实现方式参考以下文章 |
https://zhuanlan.zhihu.com/p/508886081 https://blog.csdn.net/weixin_42193813/article/details/110943055 |
简单描述一下登陆的流程: 1、登录一开始先请求验证码,后端响应codeImg和codekey
2、前端 From 表单填写用户名和密码,还有验证码、
3、数据通过网络协议Tcp三次握手建立与服务器通道,传给服务器
服务器3.1校验验证码,3.2查库,3.3解密校验密码,3.4根据user的id 通过JWT生成Token和Expire返回响应
3.1验证码校验是用 uuid 和 captcha校验的,此处uuid就是请求验证码响应的codeKey
3.2查库 3.3密码 user.getPassword().equals(new Sha256Hash(form.getPassword(), user.getSalt()).toHex()) . 3.4、返回用户认证Token 4.跳转 info请求 系统拦截token信息进行用户认证 |
关于密码加密 常见加密算法 非对称加密算法:RSA、ECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用) Hash算法:MD2、MD4、MD5、HAVAL、SHA、SHA-1、HMAC、HMAC-MD5、HMAC-SHA1(是一种不可逆的算法) SHA-256: System.out.println(DigestUtils.sha256Hex("123456")); System.out.println(new Sha256Hash("123456")); // 输出 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
加盐 String md5 = new Md5Hash(str, salt).toString();//还可以转换为 toBase64()/toHex() String sha1 = new Sha256Hash(str, salt).toString(); // 保存密码 String salt = RandomStringUtils.randomAlphanumeric(20); user.setPassword(new Sha256Hash(newPassword, salt).toHex()); user.setSalt(salt); // 验证密码 user.getPassword().equals(new Sha256Hash(form.getPassword(), user.getSalt()).toHex()) |
用户安全Tokoen 根据用户的id生成一个tonken 密钥
登录
登录成功调用 info 接口认证你的账号信息,认证就要用到 Shiro 拦截到系统token,并返回token对应用户信息 SysUserEntity userEntity = (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
getPrincipal() 如下解释
认证与授权介绍 简单说下认证,认证就是你给服务端一段信息,这段信息服务端收到会跟之前你注册的信息进行比对,比如在无任何加密的情况下将 账号 , 密码 输入 form表单发送请求到服务端,服务端根据你之前注册的账号密码进行比对,如果比对成功,说明认证成功,否则认证失败;复杂一点的认证就是 将你的账号 ,密码进行封装为另一种形式通常称为凭证,签名之类, 再将这种形式凭证的东西发给你,然后每次请求你都带上凭证而后端根据你发送的凭证信息进行解密比对,比对成功就说明认证成功,否则认证失败; 简单说下授权,现在的权限设计基本都是基于 用户 角色 , 权限 方式进行设计, 故一个用户拥有什么样的权限都基于拥有什么样的角色,我们可以给每个角色赋予不同的权限,然后认证成功之后就可以给用户进行授权(也就是将用户拥有的角色,权限返回出去就ok,每次请求的时候附带上权限信息即可,服务端再根据附带的权限信息进行判别);
认证流程:大致的认证流程是其实我们经常使用的没这么复杂, 首先就是 用户发送请求 , 我们拦截请求,在将请求 信息 通过 security manager , 其 内部就到了 Realm 进行 认证 与授权, 最后将请求到达服务端,服务端封装好数据返回给前端; shiro配置如下 /** * 认证
/** * Shiro配置 */ @Configuration public class ShiroConfig { @Bean("securityManager") public SecurityManager securityManager(OAuth2Realm oAuth2Realm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(oAuth2Realm); securityManager.setRememberMeManager(null); return securityManager; } @Bean("shiroFilter") public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); shiroFilter.setSecurityManager(securityManager); //oauth过滤 Map<String, Filter> filters = new HashMap<>(); // filters.put("oauth2", new OAuth2Filter()); shiroFilter.setFilters(filters); Map<String, String> filterMap = new LinkedHashMap<>(); filterMap.put("/webjars/**", "anon"); filterMap.put("/druid/**", "anon"); filterMap.put("/sys/login", "anon"); filterMap.put("/swagger/**", "anon"); filterMap.put("/v2/api-docs", "anon"); filterMap.put("/swagger-ui.html", "anon"); filterMap.put("/swagger-resources/**", "anon"); filterMap.put("/captcha.jpg", "anon"); filterMap.put("/aaa.txt", "anon"); filterMap.put("/app/miniotest/**", "anon"); filterMap.put("/app/miniocontroller/**", "anon"); // <!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 // filterMap.put("/**", "oauth2"); shiroFilter.setFilterChainDefinitionMap(filterMap); return shiroFilter; } @Bean("lifecycleBeanPostProcessor") public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager); return advisor; } } |