对Realm进行加盐操作
在文章Realm解析中我们进行了最简单的用户名密码登陆举例,在实际中数据库是不可能存用户的密码明文的(说是这么说,还是有好多作死的公司存),目的在于:
- 公司也不能侵犯用户隐私(BAT小米笑而不语)
- 万一被拖库了,黑客也拿不到用户密码(因为密码被加密了)
什么是加盐操作
username | password | salt |
---|---|---|
admin | xxxxxxxxx | sakf3s |
在用户表单中除了password字段之外还有salt字段,salt就是英语”盐” salt是在password存入数据库之时随机生成的一个字符串,然后与密码混在一起进行hash操作,将hash值放入password字段当作密码
当用户登陆时
- 服务器取出salt
- 与用户的输入进行相同的hash算法
- hash值与password进行比较,如果一致就登陆成功
对Realm进行加盐配置
随机盐生成器
首先一个Object可以生成随机的salt以供使用
1 | <bean id="secureRandomNumberGenerate" class="org.apache.shiro.crypto.SecureRandomNumberGenerator"> |
Hash算法对象
然后还需要选择某一种Hash算法,以便加盐过程中的Hash运算,其中hashAlgorithmName字符串参考Java本身自带的Hash字符串名
1 | <bean id="sha512Matcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> |
Salt和Hash注入Realm
与文章Realm解析不同,这里authenticationQuery的SQL语句不仅要获得password,还要获得salt
其中saltStyle分为四种
saltStyle | salt机制 |
---|---|
NO_SALT | 默认,密码没有经过加盐 |
CRYPT | 密码是以Unix加密方式储存的 |
COLUMN | salt是单独的一列储存在数据库中 |
EXTERNAL | salt没有储存在数据库中,需要通过JdbcRealm.getSaltForUser(String)函数获取 |
最常用的方式就是第三个 COLUMN
1 | <bean id="sampleRealm" class="org.apache.shiro.realm.jdbc.JdbcRealm"> |
需要注意的是,在选择了Slat之后,SQL语句一定要先获得password后获得salt,Realm会按照这个顺序区分哪个字符串是密码,哪个是salt,在JdbcRealm存在默认SQL语句
1 | protected static final String DEFAULT_AUTHENTICATION_QUERY = "select password from users where username = ?"; |
新用户将密码加盐放入数据库
由于sampleRealm仅仅是 获得角色和权限的逻辑 ,并不能再新建用户的时候帮我们对用户的密码进行hash,所以在新用户插入数据库的时候,我们要手动进行加盐
1 | @Autowired |
其中 HashedCredentialsMatcher 与 SecureRandomNumberGenerator 我们已经在applicationContext.xml里进行了配置以供sampleRealm使用,这里仅仅需要使用 @Autowired 引用单例即可