shiro多Realm第一次調用不生效問題

1. 因爲最近本身寫的一個項目上用到了多realm的使用,遇到了一個這樣的問題:css

  1. 本身繼承了BasicHttpAuthenticationFilter,實現了獲取token,而後直接請求api的方法,可是每次第一次調用的時候都是無效的,第二次請求又是正常的。html

如下爲配置文件前端

    @Bean
    public ShiroFilterFactoryBean shirFilter(org.apache.shiro.mgt.SecurityManager securityManager) {
        logger.debug("ShiroConfiguration.shiroFilter()");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //攔截器.
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        // 配置不會被攔截的連接 順序判斷
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/fonts/**", "anon");
        filterChainDefinitionMap.put("/img/**", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/index.html", "anon");
        filterChainDefinitionMap.put("/login.html", "anon");
        filterChainDefinitionMap.put("/register.html", "anon");
        //配置退出 過濾器,其中的具體的退出代碼Shiro已經替咱們實現了
        filterChainDefinitionMap.put("/auth/logout", "logout");
        filterChainDefinitionMap.put("/auth/login", "anon");
        filterChainDefinitionMap.put("/wx/app/login/**", "anon");
        filterChainDefinitionMap.put("/auth/register", "anon");
        //<!-- 過濾鏈定義,從上向下順序執行,通常將/**放在最爲下邊 -->:這是一個坑呢,一不當心代碼就很差使了;
        //<!-- authc:全部url都必須認證經過才能夠訪問; anon:全部url都均可以匿名訪問-->
        filterChainDefinitionMap.put("/**", "authc,token");
        // 若是不設置默認會自動尋找Web工程根目錄下的"/login.jsp"頁面
        //配置shiro默認登陸界面地址,先後端分離中登陸界面跳轉應由前端路由控制,後臺僅返回json數據
        shiroFilterFactoryBean.setLoginUrl("/unauth");
        // 登陸成功後要跳轉的連接
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //未受權界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        Map<String,Filter> filterMap=new HashedMap();
        filterMap.put("token",headerHttpAuthenticationFilter());
        shiroFilterFactoryBean.setFilters(filterMap);
        return shiroFilterFactoryBean;
    }

  2. 貼出主要的配置文件java

2.分析問題:apache

  1. 因爲第一次不正常,第二次正常,又由於shiro的權限認證是根據sessionId+過濾器實現的,每次刪除sessionId的cookie後,第一次經過token方式進行請求都會出現沒有權限的問題。json

  2. 檢查HeaderHttpAuthenticationFilter類發現正常,在該類中打斷點,發現方法可以正常進入到該方法中,而且是正常的後端

      3. 查詢shiro中的Filter調用鏈,發現ProxiedFilterChain類中是這樣進行調用的api

   

    public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
        if (this.filters != null && this.filters.size() != this.index) {
            if (log.isTraceEnabled()) {
                log.trace("Invoking wrapped filter at index [" + this.index + "]");
            }

            ((Filter)this.filters.get(this.index++)).doFilter(request, response, this);
        } else {
            if (log.isTraceEnabled()) {
                log.trace("Invoking original filter chain.");
            }

            this.orig.doFilter(request, response);
        }

    }

  獲取filters而後進行一個一個調用,查詢以及跟蹤斷點發現,authc該方式中對應的爲BasicHttpAuthenticationFiltercookie

在BasicHttpAuthenticationFilter打上斷點session

發現每次會請求到該方法上,查找緣由發現,因爲我是token請求,並無帶該參數致使的

 

問題解決:

  1. 查看ShiroConfig類中發現

        filterChainDefinitionMap.put("/**", "authc,token");

  位置放置權限filter鑑權有問題,因爲token的鑑權會比authc的權限高,自定義權限比普通的表單認證的優先級高。因此應該將其放到前面,修改成以下

 

        filterChainDefinitionMap.put("/**", "token,authc");

  2. 重啓項目,運行正常了