在前一节使用数据库进行用户认证(form login using database)里,我们学习了如何把“登录帐号、密码”存储在db中,但是密码都是明文存储的,显然不太讲究。这一节将学习如何使用spring security3新加入的bcrypt算法,将登录加密存储到db中,并正常通过验证。

一、Bcrypt算法

 int t = 0;
String password = "123456";
System.out.println(password + " -> ");
for (t = 1; t <= 10; t++) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String hashedPassword = passwordEncoder.encode(password);
System.out.println(hashedPassword);
} password = "MIKE123";
System.out.println(password + " -> ");
for (t = 1; t <= 10; t++) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String hashedPassword = passwordEncoder.encode(password);
System.out.println(hashedPassword);
}

输出如下:

123456 ->
 $2a$10$.Cjkvbgr2JzGkag9IdbT.Oc/sbY7wVqLgAHws7HCxqcI7eczKtCLq
 $2a$10$OCOuRV0Wy7ncCND4LcKfMunVEWOzMOyyU95u5TkTRmJqYbsJNecEK
 $2a$10$TXttsDZUaeEb2zX6wiwN0eqREKFoCDyh81Kfa6BgAcZ2hyqPNC0Ra
 $2a$10$FfLx/gxq.FyeOBb0nbaVeusLhQjASSdY7w45i1ACl/rcYQMmhaXV2
 $2a$10$JdPXAxmuz.WTP5gxYiYseeKRSM/HTFzJJdACcDQ4MdhaaLmC0SjI.
 $2a$10$yVEWf2MrwjCyi51rUKqQle/MZb7vwcOf6Gwp.hDT2ZUchlyAtJ4pO
 $2a$10$FfJg2ATit7btKfJovL6zmug//8rzToQn7FO.fxOzo1KtNNfhWKuca
 $2a$10$pOLMkd13n7i3DtVijLEqze1zeURpjtVz5rAx1qOAPqCQvjGG/d6D.
 $2a$10$fQ32i8JsjjmqVRpiEsgT3ekTKtrfXn.JNl69beWEx0.YgdX.SEx5e
 $2a$10$78brJFSdftip0XXYx4rS6ewdu4SiSsMIBY9oNcLhAZwg3GysRGk2m
 MIKE123 ->
 $2a$10$U6KVh1NGxAIGYiM4YVgn6OAQt6ayAoLkh2lODv16rSpkS1iqfbR2C
 $2a$10$t0FlEOBLEB8VwWJVoZRrweIRV0XyoBgm29c0SMqfqRK3ZBuvhgYbS
 $2a$10$QpW6nHnWNhbTTjLq/NbzBu2Unp8ijwyPeUx2N2eMFWReFezosZ5fi
 $2a$10$LtPzoQU0IluAgvP3/WhWquUv2AcDRh2ENhAeWDquiN/spitZYe/7q
 $2a$10$Qcx7vUudzF7qzTjz.QpLKOby0tXQ4j.uqkInS1n4/6oD2r2eL0rZW
 $2a$10$yZw7cdq1y9sjX8nZhYynseWjQ4jeVv76fPmBl.sg2xPvb8cyXD8Sq
 $2a$10$kTmT6BQQE5LyRZ00Qas77.F5kxK0GxsW402ExosQswxmG.eBdgIZW
 $2a$10$SRfHDNM.m3qX5y1O7V/cp.hQqgaXnKzfxBGRhLkAF39bufejuOieu
 $2a$10$Sw5w2kTImJ5Y8UNlE/5/9OLaUgYxhCXU3P3gFBdEbs9PL8pCl60Q2
 $2a$10$0mN8kNAl9GNr0c4K1Nr0b.MIcBW0QcPHB/f20hgeBuRfwvgZXT6hG
从以上输出结果发现bcrypt算法与md5/sha算法有一个很大的区别,每次生成的hash值都是不同的,这样暴力猜解起来或许要更困难一些。同时大家可能也发现了,加密后的字符长度比较长,有60位,所以用户表中密码字段的长度,如果打算采用bcrypt加密存储,字段长度不得低于60.

二、spring-security.xml

 <beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd"> <http auto-config="true" use-expressions="true">
<intercept-url pattern="/admin**" access="hasRole('ADMIN')" />
<!-- access denied page -->
<access-denied-handler error-page="/403" />
<form-login login-page="/login" default-target-url="/welcome"
authentication-failure-url="/login?error" username-parameter="username"
password-parameter="password" />
<logout logout-success-url="/login?logout" />
<!-- enable csrf protection -->
<csrf />
</http> <!-- Select users and user_roles from database -->
<authentication-manager>
<authentication-provider>
<password-encoder ref="encoder" />
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select d_username username,d_password password, d_enabled enabled from t_users where d_username=?"
authorities-by-username-query="select d_username username, d_role role from t_user_roles where d_username=? " />
</authentication-provider>
</authentication-manager> <beans:bean id="encoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<beans:constructor-arg name="strength" value="9" />
</beans:bean> </beans:beans>

对比上一节的内容,只是增加23行、30-33行

最后要做的事情,就是把db中原来明文的密码值,改成经过bcrypt加密后的字符串即可。

tips:如果你仍然喜欢用传统的sha算法来处理密码,只要把23行改成 <password-encoder hash="sha" />  就可以了

参考文章:Spring Security password hashing example

Spring Security笔记:使用BCrypt算法加密存储登录密码的更多相关文章

  1. 使用BCrypt算法加密存储登录密码用法及好处

    //导入import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; /** *使用BCrypt算法加密存储登录密码 ...

  2. Spring Security笔记:Remember Me(下次自动登录)

    前一节学习了如何限制登录尝试次数,今天在这个基础上再增加一点新功能:Remember Me. 很多网站,比如博客园,在登录页面就有这个选项,勾选“下次自动登录”后,在一定时间段内,只要不清空浏览器Co ...

  3. Spring Security 中的 Bcrypt

    最近在写用户管理相关的微服务,其中比较重要的问题是如何保存用户的密码,加盐哈希是一种常见的做法.知乎上有个问题大家可以先读一下: 加盐密码保存的最通用方法是? 对于每个用户的密码,都应该使用独一无二的 ...

  4. Spring Security笔记:HTTP Basic 认证

    在第一节 Spring Security笔记:Hello World 的基础上,只要把Spring-Security.xml里改一个位置 <http auto-config="true ...

  5. Spring Security笔记:自定义登录页

    以下内容参考了 http://www.mkyong.com/spring-security/spring-security-form-login-example/ 接上回,在前面的Hello Worl ...

  6. Spring Security笔记:自定义Login/Logout Filter、AuthenticationProvider、AuthenticationToken

    在前面的学习中,配置文件中的<http>...</http>都是采用的auto-config="true"这种自动配置模式,根据Spring Securit ...

  7. Spring Security笔记:登录尝试次数限制

    今天在前面一节的基础之上,再增加一点新内容,默认情况下Spring Security不会对登录错误的尝试次数做限制,也就是说允许暴力尝试,这显然不够安全,下面的内容将带着大家一起学习如何限制登录尝试次 ...

  8. Spring Security笔记:使用数据库进行用户认证(form login using database)

    在前一节,学习了如何自定义登录页,但是用户名.密码仍然是配置在xml中的,这样显然太非主流,本节将学习如何把用户名/密码/角色存储在db中,通过db来实现用户认证 一.项目结构 与前面的示例相比,因为 ...

  9. Spring Security笔记:Hello World

    本文演示了Spring Security的最最基本用法,二个页面(或理解成二个url),一个需要登录认证后才能访问(比如:../admin/),一个可匿名访问(比如:../welcome) 注:以下内 ...

随机推荐

  1. JSON in JavaScript Asp.net

    首先官方网站  http://www.json.org/js.html 下载 json2.js 到Github 中下载 https://github.com/douglascrockford/JSON ...

  2. JAVA中获取路径

    内容来自于snannan_268 关键字: java中获取路径 JAVA中获取路径: 1.jsp中取得路径:   以工程名为TEST为例: (1)得到包含工程名的当前页面全路径:request.get ...

  3. Linux:kill 进程

    在使用Linux时,出现端口占用.进程已启动(但处于不可控状态)情况时如何处理? 发现已知端口被占用时,可以使用netstat -apn | grep yourPort 来查看占用该端口的进程的pid ...

  4. Java触发器CronTrigger

    摘要:如果需要像日历那样按日程来触发任务,而不是像SimpleTrigger 那样每隔特定的间隔时间触发,CronTriggers通常比SimpleTrigger更有用. 一.web.xml: < ...

  5. (原创)大数据时代:基于微软案例数据库数据挖掘知识点总结(Microsoft 决策树分析算法)

    随着大数据时代的到来,数据挖掘的重要性就变得显而易见,几种作为最低层的简单的数据挖掘算法,现在利用微软数据案例库做一个简要总结. 应用场景介绍 其实数据挖掘应用的场景无处不在,很多的环境都会应用到数据 ...

  6. Storm系列(三):创建Maven项目打包提交wordcount到Storm集群

    在上一篇博客中,我们通过Storm.Net.Adapter创建了一个使用Csharp编写的Storm Topology - wordcount.本文将介绍如何编写Java端的程序以及如何发布到测试的S ...

  7. 使用Hive或Impala执行SQL语句,对存储在Elasticsearch中的数据操作

    http://www.cnblogs.com/wgp13x/p/4934521.html 内容一样,样式好的版本. 使用Hive或Impala执行SQL语句,对存储在Elasticsearch中的数据 ...

  8. Java里面的转义字符

    转义字符是指,用一些普通字符的组合来代替一些特殊字符,由于其组合改变了原来字符表示的含义,因此称为“转义”. 常见的转义字符: \n 回车(\u000a) \t 水平制表符(\u0009) \b 空格 ...

  9. oracle操作之传输表空间

    一.传输表空间概述 什么是传输表空间,传输表空间技术始于oracle9i,不论是数据字典管理的表空间还是本地管理的表空间,都可以使用传输表空间技术:传输表空间不需要在源数据库和目标数据库之间具有同样的 ...

  10. hadoop如何处理长时间运行不完成的map/reduce 任务?

    如果某一个任务在某个节点上长时间不完成,怎么手动干预来处理这种情况?董西成博客上找到的回答:hadoop中有三种特殊的任务,failed task,killed task和speculative ta ...