shiro简单总结

代码框架

首先需要一个自定义类继承AuthorizingRealm达成shiro的realm对象
在这里我们可以去实现自定义的授权和认证

//自定义UserRealm类需要继承该类
public class UserRealm extends AuthorizingRealm {

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了授权方法");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        return info;
    }
    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("执行了认证方法");
        return null;
    }
}

之后我们需要编写shiro控制类 来实现shiro的另外两个对象

@Configuration
public class ShiroConfig {
    @Bean
    //如果我们在某个注入点需要另一个 bean,我们需要专门指出它。我们可以通过 @Qualifier 注解来做到这一点。
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        //添加过滤器
        Map<String, String> filterMap = new LinkedMap();
        return bean;
    }
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        //关联realm对象
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    //创建realm对象 需要自定义类
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }
}

shiro权限规则

/*
        anon: 无需认证就可以访问
        authc: 必须认证才能访问
        user: 必需拥有记住我功能才能用
        perms: 拥有对某个资源的权限才能访问
        role: 拥有某个角色权限才能访问
        */

实现登录验证

我们使用authc规则
在过滤器添加上你要设置权限对应的路径

 public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        //添加过滤器
        Map<String, String> filterMap = new LinkedMap();
        filterMap.put("/user/*","authc");
        bean.setFilterChainDefinitionMap(filterMap);
        //设置登录请求
        bean.setLoginUrl("/toLogin");
        return bean;
    }

同时我们要在登录页面提交时去调用shiro提供的登录方法

 @RequestMapping("/login")
    public String login(String username,String password,Model model){
        //获取当前用户
        Subject subject= SecurityUtils.getSubject();
        //封装当前用户数据
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            //执行登录方法
            subject.login(token);
            return "index";
        }//用户名不存在异常
        catch (UnknownAccountException e){
            model.addAttribute("msg","用户名错误");
            return "login";
        }
        catch (IncorrectCredentialsException e){
            model.addAttribute("msg","密码错误");
            return "login";
        }
    }

还要完善认证方法

//认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("执行了认证方法");
        //连接真实数据库

        UsernamePasswordToken usertoken=(UsernamePasswordToken) token;
        HashMap<String,Object> map=new HashMap<>();
        //在前面我们调用subject.login(token); 时吧token传进去了 
        //所以可以通过token对象获得密码和用户名
        map.put("name",usertoken.getUsername());
        List<User> users = userMapper.selectByMap(map);
        if(users.size()==0){
            return null;
        }
        //第一个参数将user对象传进去 使得后续授权可以获得user对象
        //第二个参数要吧密码传进去 让shiro做密码验证
        //第三个参数可以为空
        return new SimpleAuthenticationInfo(users.get(0),users.get(0).getPassword(),"");
    }

这样简单的登录功能就实现了(点击要权限的网页如果没有权限就会跳到登录页面 登录成功后即可访问权限页面)

实现自定义授权

首先要在数据库有对应的权限字段(这里我们只考虑只有一种权限的情况)

为页面授权 授权的字符串一定要同名!

public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        //添加过滤器
        Map<String, String> filterMap = new LinkedMap();
        //perms: 拥有对某个资源的权限才能访问
        //设置一个自定义权限字符串 没有权限访问会跳到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;
    }

之后我们要完善授权方法

//授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了授权方法");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        Subject subject= SecurityUtils.getSubject();
        //获得当前用户
        User currentuser = (User) subject.getPrincipal();
        //添加权限 名字对应自己设置的字符串
        info.addStringPermission(currentuser.getPerms());
        //info.addStringPermission("user:add");
        return info;
    }

即可实现授权

posted @ 2021-08-23 16:29  一个经常掉线的人  阅读(76)  评论(0)    收藏  举报