SpringSecurity

SpringSecurity新老密码迭代的说明

前几天给的一个需求,让兼容老版本的密码,还要可以选择加密方式

springSecurity的简单使用

新老系统的迭代,还有加密算法的随机加密

用户登录的方式–交给框架管理

package com.itheima.security;

import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.pojo.Permission;
import com.itheima.pojo.Role;
import com.itheima.pojo.SysUser;
import com.itheima.service.UserService;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.ArrayList;
import java.util.List;


public class SpringSecurityUserService implements UserDetailsService {

    @Reference
    private UserService userService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //从数据库查询用户对象
        SysUser sysUser = userService.queryByUsername(username);
        if (sysUser == null) {
            return null;
        }
        //创建权限集合
        List<GrantedAuthority> list = new ArrayList<>();
        //遍历角色集合
        for (Role role : sysUser.getRoles()) {
            list.add(new SimpleGrantedAuthority(role.getKeyword()));
            //遍历角色所包含的权限集合
            for (Permission permission : role.getPermissions()) {
                list.add(new SimpleGrantedAuthority(permission.getKeyword()));
            }
        }
        //包装UserDetails ,返回给权限框架
        User user = new User(sysUser.getUsername(), sysUser.getPassword(), list);
        return user;
    }
}

xml的配置

   
    <bean id="userDetailsService" class="com.itheima.security.SpringSecurityUserService"></bean> 
    <security:authentication-manager>
        <security:authentication-provider user-service-ref="userDetailsService">
            <security:password-encoder ref="passwordEncoder"/>
        </security:authentication-provider>
    </security:authentication-manager>
    <security:global-method-security pre-post-annotations="enabled" />
    <bean id="passwordEncoder" class="org.springframework.security.crypto.factory.PasswordEncoderFactories"
          factory-method="createDelegatingPasswordEncoder"/>

更改的随机加密算法

这个地方有一个坑,不知道是不是框架的原因当使用这种加密方式的时候会出现问题,最好不是用这种加密的方式。此处的工具类我给注掉了,有大神的话可以解惑????????

encoders.put(“scrypt”, new SCryptPasswordEncoder());


    //获取随机的加密对象
    public static DelegatingPasswordEncoder getDelegatingPasswordEncoder(){
        //获取安全框架中多种加密方式的map集合
        Map<String, PasswordEncoder> encoders = new HashMap<>();
        encoders.put("bcrypt", new BCryptPasswordEncoder());
        encoders.put("ldap", new LdapShaPasswordEncoder());
        encoders.put("MD4", new Md4PasswordEncoder());
        encoders.put("MD5", new MessageDigestPasswordEncoder("MD5"));
        //TODO 明文加密不使用
//        encoders.put("noop", NoOpPasswordEncoder.getInstance());
        encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
        //TODO 这个加密方式不能使用,会报错抛异常
//        encoders.put("scrypt", new SCryptPasswordEncoder());
        encoders.put("SHA-1", new MessageDigestPasswordEncoder("SHA-1"));
        encoders.put("SHA-256", new MessageDigestPasswordEncoder("SHA-256"));
        encoders.put("sha256", new StandardPasswordEncoder());

        //获取所有的Key
        Set<String> keys = encoders.keySet();
        ArrayList<String> passwordKeys = new ArrayList<>(keys);

        //使用随机数获取索引
        int index = new Random().nextInt(passwordKeys.size());
        return new DelegatingPasswordEncoder(passwordKeys.get(index), encoders);
    }

用户的添加加密

public Result add(Integer[] roleIds, @RequestBody SysUser user){
        long count = userService.findCountByUsername(user);
        if(count > 0){
            return new Result(false,MessageConst.QUERY_USERNAMECOUNT_SUCCESS);
        }
        log.debug("=========开始添加用户============");
        log.debug("roleIds :"+roleIds+","+"user :"+user);
        //获取前端的密码
        String password = user.getPassword();
       //使用随机加密对象进行加密
        DelegatingPasswordEncoder delegatingPasswordEncoder = PasswordUtils.getDelegatingPasswordEncoder();
        password = delegatingPasswordEncoder.encode(password);
        //更改密码
        user.setPassword(password);
        userService.add(roleIds,user);
        log.debug("添加用户成功");
        return new Result(true,MessageConst.ADD_USER_SUCCESS);
    }

修改密码的时候需要手动解密

 public Result editPassword( @RequestBody Map<String,String> map){
        log.debug("map:"+map);
        String username = map.get("username");
        String password = map.get("password");
        String newPassword = map.get("newPassword");
        DelegatingPasswordEncoder delegatingPasswordEncoder = PasswordUtils.getDelegatingPasswordEncoder();
        newPassword = delegatingPasswordEncoder.encode(newPassword);
        //通过用户名查询用户的原密码
        String passwordDB = userService.findPasswordByUsername(username);
        //将用户输入的原密码与数据库里面的密码进行比对
        boolean b = passwordEncoder.matches(password, passwordDB);
        if(b){
            userService.editPassword(username,newPassword);
            return new Result(true,MessageConst.EDIT_PASSWORD_SUCCESS);
        }else{
            return new Result(false,"用户名密码校验错误");
        }
    }

扎心:第一次使用的时候不知道怎么兼容密码,最后才知道框架完全给解决了,扎心了,加密的时候会自动在密码之前加前缀{xxx}指定使用的加密方式,如果老版本的系统没有使用这种加密方式,如果框架里边集成了当前老版本的加密方式,直接在校验的时候手动拼接上加密方式就可以了{XXX}+密码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值