Springboot整合shiro学习笔记

1、通过shiro进行带盐加密,需要User表中有一个salt字段;

①md5加密:
用户密码是明文,这样是有巨大风险的。
所以,通常都会采用非对称加密,什么是非对称呢?就是不可逆的,而 md5 就是这样一个算法.
如代码所示 123 用 md5 加密后,得到字符串: 202CB962AC59075B964B07152D234B70
这个字符串,却无法通过计算,反过来得到源密码是 123.
这个加密后的字符串就存在数据库里了,下次用户再登陆,输入密码 123, 同样用md5 加密后,再和这个字符串一比较,就知道密码是否正确了。如此这样,既能保证用户密码校验的功能,又能保证不暴露密码。

②盐:
上面讲了md5加密,但是md5加密又有一些缺陷:

  1. 如果我的密码是 123,你的也是 123, 那么md5的值是一样的,那么通过比较加密后的字符串,我就可以反推过来,原来你的密码也是123.
  2. 与上述相同,虽然 md5 不可逆,但是我可以穷举法呀,我把特别常用的100万或者更多个密码的 md5 值记录下来,比如12345的,abcde的。 相当一部分人用的密码也是这些,那么只要到数据库里一找,也很快就可以知道原密码是多少了。这样看上去也就破解了,至少一部分没有想象中那么安全吧。
    为了解决这个问题,引入了盐的概念。 盐是什么意思呢? 比如炒菜,直接使用md5,就是对食材(源密码)进行炒菜,因为食材是一样的,所以炒出来的味道都一样,可是如果加了不同分量的盐,那么即便食材一样,炒出来的味道也就不一样了。

所以,虽然每次 123 md5 之后都是202CB962AC59075B964B07152D234B70,但是 我加上盐,即 123+随机数,那么md5值不就不一样了吗? 这个随机数,就是盐,而这个随机数也会在数据库里保存下来,每个不同的用户,随机数也是不一样的。再就是加密次数,加密一次是202CB962AC59075B964B07152D234B70,我可以加密两次呀,就是另一个数了。 而黑客即便是拿到了加密后的密码,如果不知道到底加密了多少次,也是很难办的。

2、提供通过JPA进行验证的Realm,继承AuthorizingRealm:
public class JPARealm extends AuthorizingRealm
JPARealm 中有doGetAuthenticationInfo()方法,验证信息:

@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String userName = token.getPrincipal().toString();
        User user = userService.getByName(userName);
        String passwordInDB = user.getPassword();
        String salt = user.getSalt();
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userName, passwordInDB, ByteSource.Util.bytes(salt),
                getName());
        return authenticationInfo;
    }

用户登录时,在登录方法中:

Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(name,userParam.getPassword());
subject.login(token);

放到token中,doGetAuthenticationInfo方法获取token,创建SimpleAuthenticationInfo对象,让输入密码加上盐进行加密与数据库中的密码进行比对;

3、shiro配置:

  1. getJPARealm() 指定了 Realm 使用 JPARealm。
  2. hashedCredentialsMatcher() 指定了 加密算法使用 md5,并且混进行2次加密。
@Configuration
public class ShiroConfiguration {
    @Bean
    public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }
 
    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean  = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        return shiroFilterFactoryBean;
    }
     
    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
        securityManager.setRealm(getJPARealm());
        return securityManager;
    }
 
    @Bean
    public JPARealm getJPARealm(){
        JPARealm myShiroRealm = new JPARealm();
        myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return myShiroRealm;
    }
 
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        hashedCredentialsMatcher.setHashIterations(2);
        return hashedCredentialsMatcher;
    }
 
    /**
     *  开启shiro aop注解支持.
     *  使用代理方式;所以需要开启代码支持;
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}

4、subject代表当前用户状态,在登录拦截器判断是否登录时:

@GetMapping("/forelogout")
public String logout( ) {
    Subject subject = SecurityUtils.getSubject();
    if(subject.isAuthenticated())
        subject.logout();
    return "redirect:home";
}

如果已登录,subject会是已验证状态,若未登录,没有已验证状态;

学习过程中的一些理解,做点笔记以便回顾,若有理解不当的地方,欢迎指教~

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值