配置监听类,关联给SessionManager
<bean> ... <property> <list> <bean></bean> </list> </property> ... </bean> 9.3 Session检测用户如果没有主动退出登录,只是关闭浏览器,则session是否过期无法获知,也就不能停止session。
为此,shiro提供了session的检测机制,可以定时发起检测,识别session过期 并停止session。
<!-- sessionManager默认开启session检测机制 --> <bean> ... <!-- 开启检测器,默认开启 --> <property value="true"/> <!--- 检测器运行间隔,单位:毫秒 默认1小时 //检测到过期后,会直接将session删除 protected void afterExpired(Session session) { if (isDeleteInvalidSessions()) { delete(session); } } --> <property value="3600000"/> ... </bean>如上,通过检测器,定时的检测session,并及时移除无效session,释放资源。
十、加密用户的密码是不允许明文存储的,因为一旦数据泄露,用户的隐私信息会完全暴露。
密码必须结果加密,生成密文,然后数据库中只存储用户的密码的密文。
在加密过程中需要使用到一些"不可逆加密",如 md5,sha等
所谓不可逆是指:
加密函数A, 明文 “abc”, A("abc") = "密文",不能通过 "密文" 反推出 "abc",即使密文泄露密码仍然安全。
10.1 加密介绍shiro支持hash(散列)加密,常见的如 md5, sha等
基本加密过程
md5(明文),sha(明文) 得到明文的密文,但明文可能比较简单导致密文容易被破解。
加盐加密过程
系统生成一个随机salt="xxxxxx", md5(明文+salt) ,sha(明文+salt),则提升了密文的复杂度。
加盐多次迭代加密过程
如果迭代次数为2,则加密2次: md5(明文+salt)=密文a , md5(密文a+salt)=最终密文
sha(明文+salt)=密文a , sha(密文a+salt)=最终密文
则进一步提升了密文的复杂度,和被破解的难度。
加密过程中建议使用salt,并指定迭代次数,迭代次数的建议值1000+
实例代码:
String password="abc";//密码明文 String salt=UUID.randomUUID().toString();//盐 Integer iter = 1000;//迭代次数 String pwd = new Md5Hash(password, salt,iter).toString(); //md5加密 String pwd = new Md5Hash(password, salt, iter).toBase64(); //加密后转base64 String pwd = new Sha256Hash(password, salt, iter).toString();//sha256加密 String pwd = new Sha256Hash(password, salt, iter).toBase64();//加密后转base64 String pwd = new Sha512Hash(password, salt, iter).toString();//sha256加密 String pwd = new Sha512Hash(password, salt, iter).toBase64()//加密后转base64 10.2 加密增加用户,或修改用户密码时,涉及到密码的加密
在注册用户的业务中,对用户提交的密码加密即可。注意:之前的用户表,并未考虑存储加密相关信息,所以此时需要对用户表做出改进,
加一列【 salt varchar(50) 】,用于存储每个用户的盐。
class UserServiceImpl implements UserService{ @Autowired private UserDAO userDAO; public void createUser(User user){ user.setSalt(UUID.randomUUID().toString());//设置随机盐 //设置加密属性:sha256算法,随机盐,迭代1000次 Sha256Hash sha256Hash = new Sha256Hash(user.getPassword(),user.getSalt(),1000); //将用户信息 (包括密码的密文 和 盐) 存入数据库 user.setPassword(sha256Hash.toBase64());//密文采用base64格式化 userDAO.createUser(user); } } 10.3 密码比对登录认证身份时,涉及到密码 比对 过程
注意,加密过程中使用的加密属性,和此处使用的加密属性 必须一致:
【sha256,迭代1000次,使用base64格式化密文】
10.3.1 指定比对器 <!-- 声明realm --> <bean> <property ref="userService"/> <!-- 此属性如果通过注解注入,则需要将注解加载set方法上,不能用在属性上。 此属性是父类属性,所以只有在set方法上注入,才能覆盖父类属性值。 --> <property> <bean> <property value="SHA-256"/> <!-- true means hex encoded, false means base64 encoded --> <property value="false"/> <property value="1000"/> </bean> </property> </bean> 10.3.2 修改RealmdoGetAuthenticationInfo方法的返回值中需要添加salt: