在使用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></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两种方法,因为这两种可以配置,而不是眉毛胡子一把抓。