springboot继承shiro

一般来说,都要一个ShiroConfig类(名字因人而异)来配置下shiro,直接上代码

@Configuration
public class ShiroConfig {

    /**
     * ShiroFilterFactoryBean 处理拦截资源文件问题。
     * 注意:单独一个ShiroFilterFactoryBean配置是或报错的,以为在
     * 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager
     *
     * Filter Chain定义说明 1、一个URL可以配置多个Filter,使用逗号分隔 2、当设置多个过滤器时,全部验证通过,才视为通过
     * 3、部分过滤器可指定参数,如perms,roles
     *
     */
    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/");


        // 拦截器.
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        // 配置不会被拦截的链接 顺序判断
        filterChainDefinitionMap.put("/", "anon");
        filterChainDefinitionMap.put("/login.html", "anon");
        filterChainDefinitionMap.put("/register.html", "anon");
        filterChainDefinitionMap.put("/findPassword.html", "anon");
        filterChainDefinitionMap.put("/static/**", "anon");
        filterChainDefinitionMap.put("/user/login", "anon");
        filterChainDefinitionMap.put("/user/sendEmail", "anon");
        filterChainDefinitionMap.put("/user/checkYzm", "anon");
        filterChainDefinitionMap.put("/user/register", "anon");
        filterChainDefinitionMap.put("/user/sign", "anon");
        filterChainDefinitionMap.put("/article/**", "anon");
        filterChainDefinitionMap.put("/comment/**", "anon");
        filterChainDefinitionMap.put("/image/**", "anon");
        filterChainDefinitionMap.put("/userImage/**", "anon");
        filterChainDefinitionMap.put("/adminLogin.html", "anon");
        filterChainDefinitionMap.put("/toVipPage", "anon");
        filterChainDefinitionMap.put("/toDeclarePage", "anon");
        filterChainDefinitionMap.put("/favicon.ico", "anon");
        filterChainDefinitionMap.put("/alipay/notifyUrl", "anon");
        filterChainDefinitionMap.put("/weixinpay/notifyUrl", "anon");

        // 配置退出过滤器,其中的具体的退出代码Shiro已经替我们实现了
        filterChainDefinitionMap.put("/logout", "logout");


        // <!-- 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
        // <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
        filterChainDefinitionMap.put("/**", "authc");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置realm.
        securityManager.setRealm(myRealm());
        return securityManager;
    }

    /**
     * 身份认证realm; (这个需要自己写,账号密码校验;权限等)
     *
     * @return
     */
    @Bean
    public MyRealm myRealm() {
        MyRealm myRealm = new MyRealm();
        return myRealm;
    }

    /**
     * Shiro生命周期处理器
     * @return
     */
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }
    /**
     * 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
     * 配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能
     * @return
     */
    @Bean
    @DependsOn({"lifecycleBeanPostProcessor"})
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }
}

上面只有MyRealm需要自己去定义,然后ShiroFilterFactoryBean 这个方法需要看下路径是怎么拦截的,其他的基本就这样(可能我的比较简单啊)

然后上MyRealm的代码

public class MyRealm extends AuthorizingRealm {

    @Resource
    private UserService userService;

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String userName=(String) SecurityUtils.getSubject().getPrincipal();
        User user=userService.findByUserName(userName);
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        Set<String> roles=new HashSet<String>();
        if("管理员".equals(user.getRoleName())){
            roles.add("管理员");
            info.addStringPermission("进入管理员主页");
            info.addStringPermission("生成所有帖子索引");
            info.addStringPermission("分页查询资源帖子信息");
            info.addStringPermission("跳转到修改帖子页面");
            info.addStringPermission("修改帖子");
            info.addStringPermission("图片上传");
            info.addStringPermission("删除帖子");
            info.addStringPermission("跳转到帖子审核页面");
            info.addStringPermission("修改状态");
            info.addStringPermission("修改热门状态");

            info.addStringPermission("分页查询评论信息");
            info.addStringPermission("修改评论状态");
            info.addStringPermission("删除评论");

            info.addStringPermission("分页查询用户信息");
            info.addStringPermission("修改用户VIP状态");
            info.addStringPermission("修改用户状态");
            info.addStringPermission("重置用户密码");
            info.addStringPermission("用户积分充值");

            info.addStringPermission("分页查询资源类别信息");
            info.addStringPermission("添加或者修改类别信息");
            info.addStringPermission("删除类别信息");
            info.addStringPermission("根据id查询资源类别实体");

            info.addStringPermission("分页查询友情链接");
            info.addStringPermission("添加或者修改友情链接");
            info.addStringPermission("删除友情链接");
            info.addStringPermission("根据id查询友情链接实体");

            info.addStringPermission("修改管理员密码");
            info.addStringPermission("安全退出");
        }
        info.setRoles(roles);
        return info;
    }

    /**
     * 登录权限认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String userName=(String)token.getPrincipal();
        User user=userService.findByUserName(userName);
        if(user!=null){
            AuthenticationInfo authcInfo=new SimpleAuthenticationInfo(user.getUserName(),user.getPassword(),"xx");
            return authcInfo;
        }else{
            return null;
        }
    }

doGetAuthenticationInfo是登录验证,把登录那部分的代码一起上,一起讲,可能比较方便

关键代码:

执行到这一步的时候,先去MyRealm的登录验证的doGetAuthenticationInfo下面的方法,然后先先执行完这个方法,再返回authcInfo,即上面获取的token,如果登录错误,就返回空的,报错

 顺便提一下,这里shiro是先判断登录输入的username和数据库查到的username是否存在,如果不存在,直接报错

如果存在再判断通过username查询出来的password和登录时候输入的password是否一致,如果一致,才算登录成功

原文地址:https://www.cnblogs.com/share-record/p/12295751.html