安全框架shiro学习

今天看了一下shiro,学习了一下如何使用。
首先第一个感觉就是和spring security相比感觉很像。
因为都是安全框架,所以作用都是为了认证和授权。spring security的核心是3个重载的configure,而shiro我只是做了个小demo,很多没了解全。就目前的感觉,核心是getDefaultWebSecurityManager和getShiroFilterFactoryBean方法。
如果类比的话,getShiroFilterFactoryBean其实就是重载http请求的configure方法,里面定义了各个路径需要什么权限才能方法。
如下:

@Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
        
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        
        //设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        
        //添加Shiro内置过滤器
     /*   *
         * Shiro内置过滤器,可以实现权限相关的拦截器
         *    常用的过滤器:
         *       anon: 无需认证(登录)可以访问
         *       authc: 必须认证才可以访问
         *       user: 如果使用rememberMe的功能可以直接访问
         *       perms: 该资源必须得到资源权限才可以访问
         *       role: 该资源必须得到角色权限才可以访问
         */
        Map<String,String> filterMap = new LinkedHashMap<String,String>();
        filterMap.put("/add", "authc");
        filterMap.put("/update", "authc");
        
        filterMap.put("/testThymeleaf", "anon");
        //放行login.html页面
        filterMap.put("/login", "anon");
        
        //授权过滤器
        //注意:当前授权拦截后,shiro会自动跳转到未授权页面
        //perms括号中的内容是权限的值
        filterMap.put("/add", "perms[user:add]");
        filterMap.put("/update", "perms[user:update]");
        
        filterMap.put("/*", "authc");
        
        //修改调整的登录页面
        shiroFilterFactoryBean.setLoginUrl("/toLogin");
        //设置未授权提示页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");
        
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        
        
        return shiroFilterFactoryBean;
    }

而getDefaultWebSecurityManager就是另一种重载了user-detail的configure
方法,在函数里设置是否内存读取还是数据库,若是数据库则设置user-realm(这是该框架类似的user-detail):

 @Bean(name="securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }

这样一看userRealm就和之前userservice依赖注入很像。
类似的写法:

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

再看userrealm的构造,很容易就联想到时要查询数据库的,这个时候和spring security就有所区别了,因为这个不是继承一个loadUserByUsername方法,而是继承了两个方法:doGetAuthenticationInfo(认证)与doGetAuthorizationInfo(鉴权),
但是实际上他们的服务内容是一致的,都是查询数据库获得用户身份与权限,只不过他将loadUserByUsername分成了两部分操作,当然,也就存入了两个对象之中,但是这并不重要,因为这两个对象都属于userRealm,其实可以理解为两种框架的实现流程都是一致的,只不过做法不同,很多小细节都不一样。

public class UserRealm extends AuthorizingRealm {

    @Autowired
    private UserService userSerivce;

    /**
     * 执行认证逻辑
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
        System.out.println("执行认证逻辑");

        //编写shiro判断逻辑,判断用户名和密码
        //1.判断用户名  token中的用户信息是登录时候传进来的
        UsernamePasswordToken token = (UsernamePasswordToken)arg0;
        User user = userSerivce.findByName(token.getUsername());

        if(user==null){
            //用户名不存在
            return null;//shiro底层会抛出UnKnowAccountException
        }

        //2.判断密码
        //第二个字段是user.getPassword(),注意这里是指从数据库中获取的password。第三个字段是realm,即当前realm的名称。
        //这块对比逻辑是先对比username,但是username肯定是相等的,所以真正对比的是password。
        //从这里传入的password(这里是从数据库获取的)和token(filter中登录时生成的)中的password做对比,如果相同就允许登录,
        // 不相同就抛出IncorrectCredentialsException异常。
        //如果认证不通过,就不会执行下面的授权方法了
        return new SimpleAuthenticationInfo(user,user.getPassword(),"");

    }

    /**
     * 执行授权逻辑
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {

        //doGetAuthorizationInfo方法可能会执行多次,权限判断次数多少,就会执行多少次
        System.out.println("执行授权逻辑1");
        System.out.println("执行授权逻辑2");

        //给资源进行授权
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //添加资源的授权字符串
        //info.addStringPermission("user:add");

        //到数据库查询当前登录用户的授权字符串
        //获取当前登录用户
        Subject subject = SecurityUtils.getSubject();
        User user = (User)subject.getPrincipal();
        User dbUser = userSerivce.findById(user.getId());

        info.addStringPermission(dbUser.getPerms());

        return info;
    }
}

shiro的注解使用还没了解,想必也是很相似,一通百通。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值