springboot整合shiro框架的一些记录

springboot整合shiro框架记录

shiro简介

  • Apache Shiro 是 Java 的一个安全(权限)框架。

  • Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE 环境,也可以用在 JavaEE 环境。

  • Shiro 可以完成:认证、授权、加密、会话管理、与Web 集成、缓存等。

shiro的基本功能

在这里插入图片描述

  • Authentication:身份认证/登录,验证用户是不是拥有相应的身份

  • Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能进行什么操作,如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限

  • Session Management:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境,也可以是Web 环境的

  • Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储

  • Web Support:Web 支持,可以非常容易的集成到Web 环境

  • Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率

  • Concurrency:Shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去

  • Testing:提供测试支持

  • “Run As”:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问

  • Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了

其实说白了shiro最关键的部分只有三个 Subject、SecurityManager、Realm,其中subject代表当前交互的对象,SecurityManager安全管理器负责管理所有的subject,最后就是 Realm 了,Shiro从Realm 获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm 获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm 得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm 看成DataSource.

springboot集成shiro的一些记录

  • 导入pom相关的依赖之后主要就是config文件中的两个配置
    -

  • ShiroConfig中主要是三个函数 从下至上依次调用

@Configuration
public class ShiroConfig {
    //shiroFilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        // 设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        // 添加shiro的内置过滤器
        /*
            anon: 无需认证就可以访问
            authc: 必须认证了才能访问
            user: 必须拥有记住我功能才能用
            perms: 拥有对某个资源的权限才能访问
            role: 拥有某个角色权限
         */

        //拦截
        Map<String, String> filterMap = new LinkedHashMap<>();
        //filterMap.put("/user/add","authc");
        //filterMap.put("/user/update","authc");
        //授权,正常情况下,没有授权会跳转到为授权页面
        filterMap.put("/user/add","perms[user:add]");
        filterMap.put("/user/update","perms[user:update]");
        filterMap.put("/user/*","authc");
        bean.setFilterChainDefinitionMap(filterMap);

        //设置登录的请求    跳转到登录页面  没有权限就返回到登录上面
        bean.setLoginUrl("/toLogin");
        //为授权页面
        bean.setUnauthorizedUrl("/noauto");
      return bean;
    }

    //DefaultWebSecurityManager

    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 关联userRealm  中间商 管理realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    //创建realm对象,需要自定义类

    @Bean
    public UserRealm userRealm() {
        return new UserRealm();
    }

    // 整合ShiroDialect: 用来整合 Shiro thymeleaf
    @Bean
    public ShiroDialect getShiroDialect() {
        return new ShiroDialect();
    }
}

  • 因为上面配置文件需要用到userRealm因此需要单独自定义UserRealm继承realm类

//自定义的UserRealm
public class UserRealm extends AuthorizingRealm {

    @Autowired
    UserService userService;
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了=>授权doGetAuthorizationInfo");

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //添加权限  用户添加
        //info.addStringPermission("user:add");

        //拿到当前登录的这个对象
        // 认证做的事情得到的用户需要在授权时候使用,
        // 需要在认证的时候最后return SimpleAuthenticationInfo(user,user.getPwd(),""); 注意是第一个参数
        Subject subject = SecurityUtils.getSubject();
        //可以通过认证得到的对象然后直接强制转换得到
        User currentUser = (User)subject.getPrincipal();//拿到user对象

        //设置当前用户的权限
        info.addStringPermission(currentUser.getPerms());

        return info;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("执行了=>认证doGetAuthorizationInfo");

        UsernamePasswordToken userToken = (UsernamePasswordToken) token;

        // 虚拟用户
        //String name = "root";
        //String password = "123456";
        //if (!userToken.getUsername().equals(name)) {
        //    return null;//抛出异常 UnknownAccountException
        //}

        // 真实数据库 用户名、密码, 数据中取
        User user = userService.queryUserByName(userToken.getUsername());

        if (user == null) {//没有这个人
            return null;
        }

        //首页
        //Subject currentSubject = SecurityUtils.getSubject();
        //Session session = currentSubject.getSession();
        //session.setAttribute("loginUser",user);


        // 密码认证,shiro做   shiro进行密码的比对更加安全
        return new SimpleAuthenticationInfo(user,user.getPwd(),"");
    }
}
  • 主要难以理解的就是controller登录过程中的login函数,其实login底层调用shiro配置中的方法执行了很多层
    -

主要原理就是:在handle中调用login方法,会将账号密码封装入token传入securityManager,然后securityManager从缓存中获取从数据库中查询的账号密码一并封装入info,最后调用match方法传入token和info进行密码匹配,匹配成功则不会出现主动抛出的异常。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小宝..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值