
数据库中经常有对数据库账号密码的加密,但是碰到一个问题,在使用UserService对密码进行加密的时候,spring security 也是需要进行同步配置的,因为spring security 中验证的加密方式是单独配置的。如下:
<authentication-manager>
<authentication-provider user-service-ref="userDetailService">
<password-encoder ref="passwordEncoder" />
</authentication-provider>
</authentication-manager>
<beans:bean class="com.sapphire.security.MyPasswordEncoder" id="passwordEncoder">
<beans:constructor-arg value="md5"></beans:constructor-arg>
</beans:bean>
如上述配置文件所示,passwordEncoder才是在spring security对账号加密校验的地方。
spring security在拦截之后,会首先对用户进行查找,通过自己定义的userDetailService来找到对应的用户,然后由框架进行密码的匹配验证。
从userDetailService得到user以后,就会进入到DaoAuthenticationProvider中,这是框架中定义的 ,然后跳入其中的authenticate方法中。
该方法会进行两个检查,分别是
* preAuthenticationChecks : 主要进行的是对用户是否过期等信息的校验,调用的方法在userDetail中有定义的。
* additionalAuthenticationChecks : 这个就是用户名密码验证的过程了。
而PasswordEncoder是我们xml中注入的bean,所以了,我们调用的则是我们自己完成的passwordEncoder
public class MyPasswordEncoder extends MessageDigestPasswordEncoder {
public MyPasswordEncoder(String algorithm) {
super(algorithm)
}
@Override
public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
return encPass.equals(DigestUtils.md5DigestAsHex(rawPass.getBytes()))
}
}
这是我对其实现的一个简单版本,调用的就是spring自带的加密算法,很简单了,当然也可以使用复杂的加密方法,这个就靠自己了
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
第一种:不使用任何加密方式的配置
[html] view plaincopy
<bean id="daoAuthenticationProvider"
class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
<!-- 明文加密,不使用任何加密算法, 在不指定该配置的情况下,Acegi默认采用的就是明文加密 -->
<!-- <property name="passwordEncoder"> <bean class="org.acegisecurity.providers.encoding.PlaintextPasswordEncoder">
<property name="ignorePasswordCase" value="true"></property> </bean> </property> -->
</bean>
第二种:MD5方式加密
[html] view plaincopy
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
<property name="passwordEncoder">
<bean class="org.acegisecurity.providers.encoding.Md5PasswordEncoder">
<!-- false 表示:生成32位的Hex版, 这也是encodeHashAsBase64的, Acegi 默认配置 true 表示:生成24位的Base64版 -->
<property name="encodeHashAsBase64" value="false" />
</bean>
</property>
</bean>
第三种:使用MD5加密,并添加全局加密盐
Java代码
[html] view plaincopy
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
<property name="passwordEncoder">
<bean class="org.acegisecurity.providers.encoding.Md5PasswordEncoder">
<property name="encodeHashAsBase64" value="false" />
</bean>
</property>
<!-- 对密码加密算法中使用特定的加密盐及种子 -->
<property name="saltSource">
<bean class="org.acegisecurity.providers.dao.salt.SystemWideSaltSource">
<property name="systemWideSalt" value="acegisalt" />
</bean>
</property>
</bean>
第四种:使用MD5加密,并添加动态加密盐
[html] view plaincopy
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
<property name="passwordEncoder">
<bean class="org.acegisecurity.providers.encoding.Md5PasswordEncoder">
<property name="encodeHashAsBase64" value="false" />
</bean>
</property>
<!-- 对密码加密算法中使用特定的加密盐及种子 -->
<property name="saltSource">
<!-- 通过动态的加密盐进行加密,该配置通过用户名提供加密盐, 通过UserDetails的getUsername()方式 -->
<bean class="org.acegisecurity.providers.dao.salt.ReflectionSaltSource">
<property name="userPropertyToUse" value="getUsername" />
</bean>
</property>
</bean>
第五种:使用哈希算法加密,加密强度为256
[html] view plaincopy
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
<property name="passwordEncoder">
<bean class="org.acegisecurity.providers.encoding.ShaPasswordEncoder">
<constructor-arg value="256" />
<property name="encodeHashAsBase64" value="false" />
</bean>
</property>
</bean>
第六种:使用哈希算法加密,加密强度为SHA-256
[html] view plaincopy
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
<property name="passwordEncoder">
<bean class="org.acegisecurity.providers.encoding.ShaPasswordEncoder">
<constructor-arg value="SHA-256" />
<property name="encodeHashAsBase64" value="false" />
</bean>
</property>
</bean>
上述配置只是在Acegi通过表单提交的用户认证信息中的密码做各种加密 *** 作。而我们存储用户密码的时候,可以通过一下程序完成用户密码 *** 作:
[java] view plaincopy
package org.hz.test
import java.security.NoSuchAlgorithmException
import org.springframework.security.authentication.encoding.Md5PasswordEncoder
import org.springframework.security.authentication.encoding.ShaPasswordEncoder
public class MD5Test {
public static void md5() {
Md5PasswordEncoder md5 = new Md5PasswordEncoder()
// false 表示:生成32位的Hex版, 这也是encodeHashAsBase64的, Acegi 默认配置 true 表示:生成24位的Base64版
md5.setEncodeHashAsBase64(false)
String pwd = md5.encodePassword("1234", null)
System.out.println("MD5: " + pwd + " len=" + pwd.length())
}
public static void sha_256() throws NoSuchAlgorithmException {
ShaPasswordEncoder sha = new ShaPasswordEncoder(256)
sha.setEncodeHashAsBase64(true)
String pwd = sha.encodePassword("1234", null)
System.out.println("哈希算法 256: " + pwd + " len=" + pwd.length())
}
public static void sha_SHA_256() {
ShaPasswordEncoder sha = new ShaPasswordEncoder()
sha.setEncodeHashAsBase64(false)
String pwd = sha.encodePassword("1234", null)
System.out.println("哈希算法 SHA-256: " + pwd + " len=" + pwd.length())
}
public static void md5_SystemWideSaltSource () {
Md5PasswordEncoder md5 = new Md5PasswordEncoder()
md5.setEncodeHashAsBase64(false)
// 使用动态加密盐的只需要在注册用户的时候将第二个参数换成用户名即可
String pwd = md5.encodePassword("1234", "acegisalt")
System.out.println("MD5 SystemWideSaltSource: " + pwd + " len=" + pwd.length())
}
public static void main(String[] args) throws NoSuchAlgorithmException {
md5() // 使用简单的MD5加密方式
sha_256() // 使用256的哈希算法(SHA)加密
sha_SHA_256() // 使用SHA-256的哈希算法(SHA)加密
md5_SystemWideSaltSource() // 使用MD5再加全局加密盐加密的方式加密
}
}
业务需求:数据库中的用户名密码明文存储在配置文件中,不是十分安全。所以将数据库中的用户名密码使用AES对称加密放入配置文件中,达到加密效果。同时也不想使用tomcat等中间件等太繁重,就使用了spring boot 轻量级框架。个人比较菜,轻喷。
关于如何搭建spring boot项目其他的人说的很详细 参考初识Spring Boot框架
入口类代码
@Controller@SpringBootApplication
@EnableAutoConfiguration
public class Aesdemo1Application {
public static void main(String[] args) {
SpringApplication.run(Aesdemo1Application.class, args)
}
}
运行时只要运行main方法 或者打包后java -jar 即可(写成.bat文件 点击运行方便简单)
@Controllerpublic class GetKeyController {
@GetMapping("/getkey")
public String greetingForm(Model model) {
model.addAttribute("passwordBean", new PasswordBean()) return "index"
}
@PostMapping("/getkey")
public String greetingSubmit(@ModelAttribute PasswordBean passwordBean) {
String s1 = AESUtil.encrypt(passwordBean.getPassword(), passwordBean.getVar1())
passwordBean.setVar2(s1)
return "result"
}
}
启动后有这里还有一个控制器类
浏览器地址输入 http://localhost:8080/getkey 即可跳转到greetingForm 方法,赋入PasswordBean属性后 跳转到index.html
PasswordBean 是自己定义的bean类 里面有password var1 var2 3个属性
index.html代码
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
<form action="#" th:action="@{/getkey}" th:object="${passwordBean}" method="post">
<p>密码: <input type="text" th:field="*{password}" /></p>
<p>加密字符: <input type="text" th:field="*{var1}" /></p>
<p><input type="submit" value="Submit" />
<input type="reset" value="Reset" /></p>
</form>
</body>
</html>
注意使用了thymeleaf框架 所以必须引入
输入要加密的和盐即可获得通过post方法到result即可获得加密后字符串
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
<h1>Result</h1>
<p th:text="'密码: ' + ${passwordBean.password}" />
<p th:text="'加密字符: ' + ${passwordBean.var1}" />
<p th:text="'加密后字符: ' + ${passwordBean.var2}" />
<a href="/getkey">Submit another message</a>
</body>
</html>
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)