美文网首页shiro
SpringBoot配置shiro

SpringBoot配置shiro

作者: 如一诺然 | 来源:发表于2018-03-16 10:33 被阅读0次

    第一步:

    在pom.xml中添加依赖

    <!-- 添加shiro依赖 begin-->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.4.0</version>
            </dependency>
      <!-- 添加shiro依赖 end-->
    

    第二步:

    添加MyShiroRealm类,继承AuthorizingRealm,重写doGetAuthenticationInfo和doGetAuthorizationInfo方法。
    1、doGetAuthenticationInfo方法用于验证登录用户的账号和密码;当用户登录时,shiro的过滤器会自动处理post请求;如果验证失败,该方法返回null或者异常(带返回message),跳转到login的post链接。
    2、doGetAuthorizationInfo方法用于获取用户的权限,权限存到SimpleAuthorizationInfo后返回。
    注:doGetAuthenticationInfo这个方法是在用户登录的时候调用的也就是执行SecurityUtils.getSubject().login()的时候调用;(即:登录验证)而doGetAuthorizationInfo方法是在我们调用SecurityUtils.getSubject().isPermitted()这个方法时会调用doGetAuthorizationInfo(),而我们的@RequiresPermissions这个注解起始就是在执行SecurityUtils.getSubject().isPermitted()。

    public class MyShiroRealm extends AuthorizingRealm{
    
        /**
         * 授权用户权限
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(
                PrincipalCollection principals) {
            System.out.println("doUserAuz11111");
            //获取用户
            User user = (User)SecurityUtils.getSubject().getPrincipal();
            SimpleAuthorizationInfo info =  new SimpleAuthorizationInfo();
            //获取用户角色
            Set<String> roleSet = new HashSet<String>();
            roleSet.add("100002");
            info.setRoles(roleSet);
            //获取用户权限
            Set<String> permissionSet = new HashSet<String>();
            permissionSet.add("sys:acc:aaaa");
            permissionSet.add("权限删除");
            info.setStringPermissions(permissionSet);
            return info;
        }
    
        /**
         * 验证用户身份,如果验证失败,返回null或者异常(带返回message),跳转到login的post链接
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(
                AuthenticationToken authcToken) throws AuthenticationException {
            System.out.println("doUserAucccccc11111");
            UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
            String username = token.getUsername();
            String password = String.valueOf(token.getPassword());
            System.out.println("passW:"+password);
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("nickname", username);
            //密码进行加密处理  明文为  password+name
            String paw = password+username;
            String pawDES = paw;//MyDES.encryptBasedDes(paw);
            map.put("pswd", pawDES);
    
            User user = new User();
            user.setId("112222");
            user.setUserName(username);
            user.setPassWord(pawDES);
    
    //        return new SimpleAuthenticationInfo(user, password, getName());
            return null;
        }
    }
    

    第三步:

    添加ShiroConfiguration(@Configuration)类,配置shiroFilter、securityManager等。

    @Configuration
    public class ShiroConfiguration {
    
        /**
         * ShiroFilterFactoryBean 处理拦截资源文件问题。
         * 注意:单独一个ShiroFilterFactoryBean配置是或报错的,以为在
         * 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager
         *
         * Filter Chain定义说明 1、一个URL可以配置多个Filter,使用逗号分隔 2、当设置多个过滤器时,全部验证通过,才视为通过
         * 3、部分过滤器可指定参数,如perms,roles
         *
         */
        @Bean
        public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
            System.out.println("ShiroConfiguration.shirFilter()");
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            shiroFilterFactoryBean.setSecurityManager(securityManager);
            //拦截器.
            Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
            // 配置不会被拦截的链接 顺序判断
            filterChainDefinitionMap.put("/static/**", "anon");
            //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
            filterChainDefinitionMap.put("/logout", "logout");
            //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
            //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
            filterChainDefinitionMap.put("/**", "authc");
            // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
            shiroFilterFactoryBean.setLoginUrl("/login");
            // 登录成功后要跳转的链接
            shiroFilterFactoryBean.setSuccessUrl("/index");
    
            //未授权界面;
            shiroFilterFactoryBean.setUnauthorizedUrl("/error");
            shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
            return shiroFilterFactoryBean;
        }
    
        @Bean
        public SecurityManager securityManager() {
            System.out.println("sec11111");
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            // 设置realm.
            securityManager.setRealm(myShiroRealm());
            // 自定义缓存实现 使用redis
            //securityManager.setCacheManager(cacheManager());
            // 自定义session管理 使用redis
            //securityManager.setSessionManager(sessionManager());
            //注入记住我管理器;
            securityManager.setRememberMeManager(rememberMeManager());
            return securityManager;
        }
    
        public MyShiroRealm myShiroRealm(){
            System.out.println("getRealm11111");
            return new MyShiroRealm();
        }
    
        /**
         * cookie对象;
         * @return
         */
        public SimpleCookie rememberMeCookie(){
            System.out.println("cookie11111");
           //这个参数是cookie的名称,对应前端的checkbox的name = rememberMe
           SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
           //<!-- 记住我cookie生效时间30天 ,单位秒;-->
           simpleCookie.setMaxAge(2592000);
           return simpleCookie;
        }
    
        /**
         * cookie管理对象;记住我功能
         * @return
         */
        public CookieRememberMeManager rememberMeManager(){
            System.out.println("cookieManager11111");
           CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
           cookieRememberMeManager.setCookie(rememberMeCookie());
           //rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)
           cookieRememberMeManager.setCipherKey(Base64.decode("3AvVhmFLUs0KTA3Kprsdag=="));
           return cookieRememberMeManager;
        }
    }
    

    如果要开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),添加以下代码:

    /**
         * Shiro生命周期处理器 * @return
         */
        @Bean
        public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
            return new LifecycleBeanPostProcessor();
        }
    /**
         * 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(SecurityManager securityManager) {
            AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
            authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
            return authorizationAttributeSourceAdvisor;
        }
    

    相关文章

      网友评论

        本文标题:SpringBoot配置shiro

        本文链接:https://www.haomeiwen.com/subject/xjjlqftx.html