Shiro加密

本文档的代码中不会放出查询数据库的代码,以及数据库表结构的SQL,这些请去案例文件中寻找。如果看不懂请先看自定义Realm

注意:Shiro并不接管注册,需要程序猿实现

下列代码是我自定义的Realm,在无参构造中设置了如何加密,在登录验证方法的倒数第二行指定了如何加盐。

/**
 * 自定义Realm,需要注入到Spring IoC中
 */
@Component
public class MyRealm extends AuthorizingRealm {
    private final String salt = "black";//盐
    public MyRealm() {
        super.setName("MyRealm");//设置Realm的名字
        //准备Shiro的加密类
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        matcher.setHashAlgorithmName("MD5");//指定加密类型
        matcher.setHashIterations(2);//指定加密次数
        super.setCredentialsMatcher(matcher);
    }
    /**
     * 完成登录认证的方法
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 获取账号信息
        String username = (String) authenticationToken.getPrincipal();
        //查询出该账号正确的密码
        String password = usersMapper.getPasswordByUsername(username);
        if (password == null)
            throw new AuthenticationException("该账号不存在,验证失败");
        // 验证密码,密码验证shiro已经实现,只用给shiro传入正确的密码就好
        AuthenticationInfo info = new SimpleAuthenticationInfo(username, password, "MyRealm");//第三个参数传入的是Realm的类名
        //加盐
        ((SimpleAuthenticationInfo) info).setCredentialsSalt(ByteSource.Util.bytes(salt));
        return info;
    }
}

下列代码是用户注册的Service,加密方式和加盐方式要和上列代码一样,否则登录认证是不会通过的。

@Service
public class UserService {
    @Autowired
    private UsersMapper usersMapper;
    @Autowired
    private UserRolesPermissionsMapper userRolesPermissionsMapper;
    private final String memberRole = "member";//会员角色
    private final String salt = "black";//盐

    /**
     * 用户注册,并默认分配角色为“member”
     *
     * @param user
     * @return
     */
    @Transactional(timeout = 5, rollbackFor = {ArithmeticException.class, Exception.class})
    public void register(Users user) throws Exception {
        if (usersMapper.getPasswordByUsername(user.getUsername()) != null) {
            throw new Exception("该用户已存在[" + user.getUsername() + "]");
        }
        usersMapper.saveUser(user.getUsername(), this.encryption(user.getPassword()));
        userRolesPermissionsMapper.setRole(user.getUsername(), memberRole);
    }

    /**
     * 加密方法,要与Shiro登录验证的加密规则一样
     * 这个方法一般只在注册时使用
     *
     * @param password 待加密的明文
     * @return
     */
    private String encryption(String password) {
        String hashAlgorithmName = "MD5";//加密算法名称
        int hashIterations = 2;//加密次数
        ByteSource credentialsSalt = ByteSource.Util.bytes(salt);//加盐
        return new SimpleHash(hashAlgorithmName, password, credentialsSalt, hashIterations).toString();
    }
}

控制器:

@RestController
public class Test {
    @Autowired
    private MyRealm myRealm;
    @Autowired
    private UserService userService;
    /**
     * 登录验证接口
     */
    @GetMapping(value = "/login", params = {"username", "password"})
    public Object test(Users user) {
        try {
            //1:构建securityManager环境
            DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
            defaultSecurityManager.setRealm(myRealm);
            //2:主体提交认证请求
            SecurityUtils.setSecurityManager(defaultSecurityManager);
            Subject subject = SecurityUtils.getSubject();
            //3:登录(Shiro接管了登录功能),如果传入的账号密码和simpleAccountRealm对象的不同则会账号或密码错误的异常
            UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
            subject.login(token);
            //3:检查对当用户是不是指定角色
            subject.checkRoles("member");
            //查看认证结果
            return "认证结果:" + subject.isAuthenticated();
        } catch (Exception e) {
            return "认证失败,错误信息为:" + e;
        }
    }
    /**
     * 注册接口
     */
    @GetMapping(value = "/register", params = {"username", "password"})
    public Object register(Users user) {
        try {
            userService.register(user);//注册
            return this.test(user);//注册成功就去登录
        } catch (Exception e) {
            return "认证失败,错误信息为:" + e;
        }
    }
}

调用注册接口:

再次调用注册接口,传入相同的账号,会提示你该账号已存在

调用登录接口

登录故意传错密码,会返回你密码错误

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值