开发者学堂课程【Spring Security知识精讲与实战演示(一):Spring Security加密认证】学习笔记与课程紧密联系,让用户快速学习知识
课程地址:https://developer.aliyun.com/learning/course/730/detail/13039
Spring Security加密认证
认证的流程已经做完,还有一些季节性的东西需要来优化,第一个,现在的认证走的全是原文,说明我们把密码截止到数据库,大家谁都进来可以看到密码是123,这样做是不合理的。我们应该存到数据库里面的密码应该是加密后的密文,要涉及到加密,我们只认得spring security,也给我们提供了一种加密方式。
我们可以来对这个加密方式先进行一个简单的测试和介绍。Create New Class中的Name填的是com.itheima.test.Encoding Test。
public class EncodingTest {
后边填写上public static void main(String[] args){BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();System out. print In(passwordEncoder).
把鼠标放在passwordEncoder.
后会出现两种方法,一种是encode(CharSequence rawPassword),rawPassword
是原文的意思,原来密码是123,把123写到CharSequence后,再返回一个String,是加密后的String。
还有一个是 matches(CharSequence rawPassword, String encodedPassword),我们来看,rawPassword 指的是原文,encodedPassword 指的是密文,写一个原文,再写一个密文,它会返回一个boolean值。如果它发现这两个密码是同一个,肯定会给你返回String,如果不是同一个,它就会给你返回boolean。当它给我一个123,我们第一次加密文,第二次进行判断,我们这再加密一下,我们就可以判断出来吗?我们在System out. print In (passwordEncoder. encode()
中填写上rawPassword:"123"),选中实行,将$2a$10$CYX90Mv0y08wR8rE19N2f0aXDJondci5uR68k2eQJm50q8ESsDMIC
粘贴复制到public class EncodingTest下边。
我们再来看一下第二次加密后的结果,将$2a$10$sfam Br judKnEeuhZGrh6.p67bUzBX/Szq3i47oagpR1kQQmlwQ7G
粘贴复制到$2a$10$CYX90Mv0y08wR8rE19N2f0aXDJondci5uR68k2eQJm50q8ESsDMIC
后,我们可以再执行一次,事不过三,三次都不一样可以推断出它永远都不一样,$2a$10$hy6Kk0fi.qTTiQx6WXX6ru9goE2FFy7xzidT75ji8N00SV4po4Fou
粘贴复制过去,我们可以发现三种都不一样。
FM5每次用完都是一样的,有一个概念叫做加盐加密,例如md 5,如果原文是123,加完密之后可能是bcaddjlj,但是需要我们注意的是,我们以前md 5123加完密之后永远是bcaddjlj,如果永远是bcaddjlj,那这安全性还可以有保障吗?只要收集大量的这种建筑盾,我拿它当配值去get一下123,就是密码。但是如果这样做就没有安全性可言了,真正用md5要加盐,加盐即例如我现在有一个规则很简单,就是破坏里边原来的味道,原来是123,我们的盐是首字母跟最后一个字母调换,若还是还不放心,可以加一个名,例如调换一下就变成321了,原来密码123,首尾交换就变成321。
若觉得这还不靠谱,我们可以加用户名,在用户名后加上xiaoming,加完密之后是另外一种,例如是dhxjndjdjn,既然是另外一种,相较于之前的会保险很多。是相对,不是绝对,因为这个盐也是人静,那这个盐如果泄露出去,这个密码就会不准了。这个密码我得到了这一串,我知道你不是密码,但是我知道盐,我们把最后的用户名去掉,首位调换我们再换回来,即我们就知道密码是123所以说这个也不保险。spring security可以做到动态加盐,动态加盐即每一次加的盐都不一样,我们永远不知道他下一次加的是什么,但是它的位置是固定的,它会分析出位置来判断是否是同一个,但是我们注意,因为盐我们是不知道的,所以我们不能判断两个密码是否是同一个。
所以package方法就是必须的。上述就是我们介绍spring security的加盐加密。那么知道这个对象之后,我们就可以用这个对象说把我们这数据库中的密码加密,并且认证方法我们也可以改成加密。
接下来做这个操作,右键可以控制他的舰队名。首先做第一步,我们要把当前这个加密对象放到ID容器中。这个很简单,我们写上<bean id="" class="org. springframework. security.crypto.berypt. BGryptPasswordEncoder,
此时有一个细节需要我们注意,当前这个加密对象的默认密码是passwordEncoder,ID写的就是passwordEncoder,但是我们记不住这个名字,所以有一个更靠谱的方式直接在这里边填写s,就会出现security:password-encoder ref="",
再把passwordEncoder粘贴复制进去,此时就更靠谱了,不管我们的密码是啥,我这都可以用,但是我们需要注意,如果我们默认ID的话,我们得把加密对象放入到IOC容器中这一句放到这个认证提供经济来源这个配置的上面,放下面不好选。
如果我们直接通过security:password-encoder ref="passwordEncoder"引用过来,我们就可以随便放置。此时我们的ioc容器中就有了一个加密对象,并且我们告诉spring security,
此时需要注意,就不要再配置那句话,配置也不起作用。此时它就是加密认证,加密认证这就这么简单,做完之后我们想,在保存数据库中的对象,它不是加密的。
我们可以在这里边做一个修改,我们注入@Autowired private BCryptPasswordEncoder passwordEncoder,
注入之后就会变得很简单,我们再输入user. setPassword(passwordEncoder. encode(user. getPassword())
,再次保存到数据库中密码就是密文了。到此,加密工作就做完了,保存到数据库中密码是加密的,认证的时候也是加密的。
重新启动,启动的时候有一个问题。问题是此时认证还能通过吗?用户名我们还是需要输入xiaoming,密码是123,此时是没有用的。因为此时它认为123是密文,但是我们的123不是密文,所有此时我们可以再来登录一次,用户名写xiaoming,密码是123,点击登录,界面一闪而过,并没有成功,认证失败。
认证失败应该有认证失败的界面,认证失败的界面应该出现在认证时候之后,但是失败的时候并没有ROLE_USER,即没有这个角色就不能访问这个界面,同理,不能出现这个页面,系统就会自己进行跳页,authentication-failure-url="/failer.jsp就不起作用,所以要将failer.jsp进行释放,把failer.jsp复制粘贴到<security:http pattern="/failer.jsp"security-"none"/)
里,这样的话页面不认证也可以访问了。
但是它没有必要经过后续的过滤器,所以把它放到最外面就行了,此时再来重新启动,重新启动之后,此时就能跳转到我们的认证失败界面,启动之后后再次弹跳出登录页面,再次输入用户名xiaoming,密码是123,意看现点击登录。此时就可以到认证失败页面。若我们想成功,我们可以在Encoding里$2a$10$CYX90Mv0y08wR8rE19N2f0aXDJondci5uR68k2eQJm50q8ESsDMIC
粘贴复制password栏里,这里只能手动更改。进行刷新后,此时就更改成了$2a$10$CYX90Mv0y08wR8rE19N2f0aXDJondci5uR68k2eQJm50q8ESsDMIC。
再进行刷新,刷新之后再次返回到登录界面,输入用户名 xiaoming,密码是123,点击登录,登录成功。这一次就是加密认证。以上是加密认证这一部分,以后在实地公司做开发的时候,一定要注意我们数据库中的用户密码一定要是加密的状态。