SpringBoot和Shiro的极简整合

本文详细介绍了Shiro框架的三大核心组件:Subject(主体)、SecurityManager(安全管理器)和Realm(安全数据存储)。讲解了它们的作用和整合过程,包括自定义UserRealm和如何配置Shiro Filter。
摘要由CSDN通过智能技术生成

shiro安全框架的三大核心

1,Subject(主体)

相当于shiro的主题,shiro的核心API就是Subject,Subject代表的就是当前的用户,这个用户不是指具体的某一个人,可以说与当前应用交互的任何东西都是Subject,与Subject的所有交互都会委托给SecurityManager来执行,可以理解为Subject只是一个充当门面的,真正的幕后老大是SecurityManager,SecurityManager才是实际的执行者。

2,SecurityManager(安全管理器)

subject的幕后操作的就是SecurityManager

所有与安全有关的操作都会与SecurityManager进行交互,并且SecurityManager管理者所有的Subject,可以看出它才是Shiro的核心,它负责与Shiro的其他组件进行交互,它相当于SpringMvc中的dispatcherServlet(前端控制器)的角色。

3,Realm

就好比mybatis的datasource,所有的用户信息的账号密码都存储在Realm中,Realm中存储安全数据(用户,角色,权限)

Shiro从Realm获取安全数据(用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法,也需要从Realm获取用户的角色\权限来判断用户是否能进行一系列操作。可以把Realm看作DataSource数据源.

整合Realm

整合其实就是shiro中的三大核心逐步整合到容器中去,首先第一步,整合realm,自定义UserRealm继承自AuthorizingRealm这个类,里面主要有认证和授权的两个步骤,将用户的业务类也注入进来

    @Autowired
    UserService userService;

授权

首选来看授权的逻辑,授权就是给用户分配自己设置权限

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    System.out.println("执行了授权");
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    //添加权限
    info.addStringPermission("user:add");
    //拿到当前登录的对象
    Subject subject = SecurityUtils.getSubject();
    User currentUser = (User) subject.getPrincipal();//拿到user对象
    //设置当前用户的权限
    info.addStringPermission(currentUser.getPerms());
    //return info;
    return info;
}

认证

密码的认证是shiro做的,在方法的逻辑中只用做用户的认证

@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("执行了认证");
        //用户名密码,数据库中取
//        String name="root";
//        String password="123456";
        //连接真实的数据库
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
//        if(!userToken.getUsername().equals(name)){
//            return null;//抛出异常
//        }
        User user = userService.queryByName(userToken.getUsername());
        if (null == user) {
            return null;
        }
        //密码认证,shiro做
        return new SimpleAuthenticationInfo("user", user.getPwd(), "");
    }

整合SecurityManage

在安全管理器的整合中需要注入刚才整合的UserRealm,所以首先编写一个配置类,在配置类中注入Bean,这个配置类加上@Configuration注解

首选注入UserRelam的Bean

@Bean(name = "Realm")
public UserRealm userRealm() {
    return new UserRealm();
}

同样,如果需要整合一些方言的话,将ShiroDialect这个类也注入进去

//整合ShiroDialect(方言):用来整合shiro和thymeleaf
@Bean
public ShiroDialect getShiroDialect() {
    return new ShiroDialect();
}

接着,就是经典的两个Bean,其中的依赖关系如下图所示:
在这里插入图片描述

这另外的两个Beand的依赖关系,看源码如图所示,两个方法对应的是层级的依赖,从底向上分别重写相应的方法就可以
在这里插入图片描述

默认的安全管理器需要注入userRealm,同理内置过滤器的整合也是这样,最后剩下的两个Bean整合结果如下:

 @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);

        //添加shiro的内置过滤器
        /*
              anon:无需认证就可以访问
              authc: 必须认证了才可以访问
              user: 必须拥有 记住我功能才能用
              perms: 拥有对某个资源的权限才可以访问:
              role: 拥有某个角色权限才能访问
            filterMap.put("/user/add","anno");
        filterMap.put("/user/update","authc");
         */

        //1,拦截
        Map<String, String> filterMap = new LinkedHashMap<>();
        //2,授权 正常情况下,未授权会跳到401
        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("/noauth");
        return bean;
    }

    @Bean(name = "defaultWebSecurityManager")
    //DafauleWebSecurityManage
    public DefaultWebSecurityManager getDefaultWebSecurityManage(@Qualifier("Realm") UserRealm Realm) {
        DefaultWebSecurityManager securityManage = new DefaultWebSecurityManager();
        //关联UserRealm
        securityManage.setRealm(Realm);
        return securityManage;
    }

就这样,基本完成了Shiro的相关整合,剩下的就是需要在项目中熟练使用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值