在使用shiro配置無授權信息的url的時候,發現這樣的一個scenario,配置好unauthorizedUrl后仍然無法跳轉,然后就在網上開始找,找了原因以及解決方案
原因,先post一個源碼:
private void applyUnauthorizedUrlIfNecessary(Filter filter) { String unauthorizedUrl = this.getUnauthorizedUrl(); if(StringUtils.hasText(unauthorizedUrl) && filter instanceof AuthorizationFilter) { AuthorizationFilter authzFilter = (AuthorizationFilter)filter; String existingUnauthorizedUrl = authzFilter.getUnauthorizedUrl(); if(existingUnauthorizedUrl == null) { authzFilter.setUnauthorizedUrl(unauthorizedUrl); } } }
注意,這里要apply這個url必須滿足兩個條件,即不為空,並且filter是AuthorizationFilter,然后,只有perms,roles,ssl,rest,port才是屬於AuthorizationFilter,而anon,authcBasic,auchc,user是AuthenticationFilter,所以unauthorizedUrl設置后頁面不跳轉
所以,就不跳轉了,那么解決方案呢,總結了一下,有下面幾種,然后分析一下各種
1,使用perms,roles,ssl,rest,port
2,配置error頁面,這針對所有的error頁面,這個挺一勞永逸的
<error-page>
<error-code>500</error-code>
<location>/error.jsp</location>
</error-page>
3,配置所有的拋出無權限異常的頁面,
<error-page> <exception-type>org.apache.shiro.authz.UnauthorizedException</exception-type> <location>/unauthorized.jsp</location> </error-page>
4,注入SimpleMappingExceptionResolver,然后配置不同異常所對應的錯誤頁面
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.apache.shiro.authz.UnauthorizedException">/errorpage/refuse</prop> </props> </property> </bean>
5,自定義異常類Reslover 捕捉異常,如果異常為無權限異常就手動就是轉發到無權頁面。
public class MyExceptionResolver implements HandlerExceptionResolver{ public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { // TODO Auto-generated method stub System.out.println("==============異常開始============="); //如果是shiro無權操作,因為shiro 在操作auno等一部分不進行轉發至無權限url if(ex instanceof UnauthorizedException){ ModelAndView mv = new ModelAndView("manage/unauth/index"); return mv; } ex.printStackTrace(); System.out.println("==============異常結束============="); ModelAndView mv = new ModelAndView("error"); mv.addObject("exception", ex.toString().replaceAll("\n", "<br/>")); return mv; } }
然后在bean中進行配置
<!-- 自定義異常處理--> <bean id="exceptionResolver" class="com.ljy.manage.resolver.MyExceptionResolver"></bean>
上述五種方法,都可以解決這個問題
我比較贊成的是4,5兩種方法,因為這兩種可以配置,而不是眉毛胡子一把抓。