zoukankan      html  css  js  c++  java
  • spring security进阶2 添加账户并对账户密码进行加密

    spring security 添加账户并对账户密码进行加密

    上一篇博文中介绍了spring security如何使用数据库中的账户进行认证登录,这次来总结下如何给数据库添加账户并对密码加密。

    上一篇:使用数据库密码进行认证

    一、原理分析

    1.1加密原理

    首先前端页面发送注册的账户信息到controller层,然后依次经过service层和dao层,最后入库。其中对密码的加密应该放在service层进行,加密后再入库。

    spring security中有一个加密类BCryptPasswordEncoder可以用来对密码进行加密,调用其中的encode方法返回一个加密后的字符串

    public String encode(CharSequence rawPassword) {
    		String salt;
    		if (strength > 0) {
    			if (random != null) {
    				salt = BCrypt.gensalt(strength, random);
    			}
    			else {
    				salt = BCrypt.gensalt(strength);
    			}
    		}
    		else {
    			salt = BCrypt.gensalt();
    		}
    		return BCrypt.hashpw(rawPassword.toString(), salt);
    }
    

    使用时可以在spring的配置文件中配置一个加密类的bean,这样在service中可以直接注入

    加密后数据库中存储的是加密过后的字符串。

    1.2加密后的登录过程

    对密码进行加密后数据库中存储的是加密字符串,用户发起登录请求后,框架会使用相同的加密算法对前端传递的密码进行加密并得到加密字符串,然后和数据库中查询到的字符串进行对比。

    二、代码实现

    具体的工程代码可以参考我的工程示例,下文中只给出了和添加用户相关的部分。

    在配置文件中配置加密类

    <bean id="passwordEncoder" 	    class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
        </bean>
    

    2.1添加用户的页面如下, register.html

    <html>
        <head>
            <meta charset="UTF-8">
            <title>注册页面</title>
        </head>
        <body>
    
        <form action="/user/add.do" method="post">
            用户名:<input type="text" name="username" placeholder="请输入用户名"><br>
            密 码:<input type="password" name="password" placeholder="请输入密码"><br>
            <input type="submit" value="注册">
        </form>
        </body>
    </html>
    

    2.2controller层创建一个增加用户的方法

    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @Autowired
        private IUserService userService;
    
        @PostMapping("/add")
        public String add(UserInfo userInfo){
            userService.add(userInfo);
            return "success";
        }
    }
    

    2.3service层

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;
    ...//省略其他
    @Override
    public void add(UserInfo userInfo) {
        //对密码加密
        userInfo.setPassword(passwordEncoder.encode(userInfo.getPassword()));
        userDao.add(userInfo);
    }
    

    这里的passwordEncoder就是在配置文件中配置的加密bean,注入后可以直接使用

    dao层这里就不再列举了。

    三、测试

    启动工程并成功登录后,跳转到首页,

    选择注册新账号后跳转到注册页面

    输入账户和密码后注册,会在数据库中插入一条新的记录。


    这里我页面上输入的是 admin/admin,数据库中存储的password是加密后的

    $2a$10$URSaaafrPOCjFYvhrhQbku2/l36IJ0zH0G8xeJzf5lAH2F1JJ1ybG
    

    四、用加密后的账号登录

    此时如果使用刚刚新建的这个账号进行登录就会登录失败。因为我们并没有配置spring security认证时的加密方式,默认是不进行加密,所以会直接将前台输入的密码和数据库中的加密字符串进行比较。

    要使用这个账号登录还需要进行如下配置

    在spring security的配置文件中配置加密策略

    <security:authentication-manager>
            <!--配置使用给定的userservice完成认证-->
            <security:authentication-provider user-service-ref="userService">
                <security:password-encoder ref="passwordEncoder"/>
            </security:authentication-provider>
        </security:authentication-manager>
    
        <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
        </bean>
    

    在userService的loadUserByUsername方法中去除密码字符串上拼接的{noop}字符串,本来这个就是为了适配密码未加密的情况

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            UserInfo userInfo = userDao.findByUsername(username);
            User user=new User(userInfo.getUsername(),userInfo.getPassword(),getRoles());
            return user;
    }
    

    然后使用刚才注册的 admin/admin就可以登录成功了。

    注意如果进行了上面两部,数据库中以前的账户将不能进行登录了,因为数据库中的密码是没有加密的,而框架会对前台传递的密码进行加密后再和数据库中的比较。所以一定要记住上面新注册的这个账号admin/admin

    这里我给出admin对应的加密字符串

    $2a$10$URSaaafrPOCjFYvhrhQbku2/l36IJ0zH0G8xeJzf5lAH2F1JJ1ybG
    

    如果大家忘记了刚才注册的账号,可以在数据库中插入一条admin/admin的记录。

    五、总结

    添加账户主要是需要用spring security自带的加密类BCryptPasswordEncoder对用户密码进行加密。

    要使用新注册的账户登录就需要在配置文件中配置加密策略

    配置后原来的账号因为密码没有加密将不能使用

    六、示例工程源码

    示例工程已经上传到码云上,如果有需要欢迎大家参考

    示例工程

  • 相关阅读:
    核心动画的使用
    核心动画的使用
    核心动画的使用
    异常上报功能Bugly简介
    核心动画的使用
    一种传统的程序模块化马甲包开发架构
    定时器、多线程
    核心动画
    Core Animation 核心动画
    核心动画的使用
  • 原文地址:https://www.cnblogs.com/chengxuxiaoyuan/p/11932133.html
Copyright © 2011-2022 走看看