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. 重啓項目,運行正常了