问题背景
   
    1.使用
    
     Shiro
    
    对用户访问资源进行权限校验(授权)。
    
    2.目的:当用户访问没有权限资源时,跳转到指定页面。
    
    3.setUnauthorizedUrl(”/view/permission”)方法作用:当用户没有权限访问时跳转到”/view/permission”页面。
    
    4.但是setUnauthorizedUrl配置没有生效。
   
    @Bean //此对象中要配置一些访问规则(匿名访问的资源,认证的访问的资源)
    public ShiroFilterFactoryBean shiroFilterFactory(SecurityManager securityManager) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);
        factoryBean.setLoginUrl("/view/login");
        factoryBean.setSuccessUrl("/view/index");
        factoryBean.setUnauthorizedUrl("/view/permission");
        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/bootstrap/**", "anon");
        filterMap.put("/view/index", "anon");
        filterMap.put("/login/**", "anon");
        filterMap.put("/**", "authc");
        factoryBean.setFilterChainDefinitionMap(filterMap);
        return factoryBean;
    }
    
    
    分析
   
    1.
    
     Shiro
    
    有两个模块
    
     认证
    
    和
    
     授权
    
    ,每个模块都有
    
     独立
    
    的过滤器和异常处理方式。
    
    
     认证
    
    过滤器:anon、authc、user、authcBasic
    
    
     授权
    
    过滤器:perms、roles、ssl、rest、port
    
    2.我们的过滤器只配置了”anon”和”authc”,这两个都属于
    
     认证
    
    过滤器。
   
 Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/bootstrap/**", "anon");
        filterMap.put("/view/index", "anon");
        filterMap.put("/login/**", "anon");
        filterMap.put("/**", "authc");
    3.看源码第3行(filter instanceof AuthorizationFilter),只有属于
    
     授权
    
    的过滤器才能触发setUnauthorizedUrl()配置。
   
    private void applyUnauthorizedUrlIfNecessary(Filter filter) {
        String unauthorizedUrl = getUnauthorizedUrl();
        if (StringUtils.hasText(unauthorizedUrl) && (filter instanceof AuthorizationFilter)) {
            AuthorizationFilter authzFilter = (AuthorizationFilter) filter;
            //only apply the unauthorizedUrl if they haven't explicitly configured one already:
            String existingUnauthorizedUrl = authzFilter.getUnauthorizedUrl();
            if (existingUnauthorizedUrl == null) {
                authzFilter.setUnauthorizedUrl(unauthorizedUrl);
            }
        }
    }
4.所以我们这条代码白写
factoryBean.setUnauthorizedUrl("/view/permission");
    
    
    解决
   
    
    
    方法一
   
自定义异常处理类,不使用shiro进行页面跳转(推荐)
@ControllerAdvice
public class MyControllerAdvice {
    @ExceptionHandler(UnauthorizedException.class)
    public ModelAndView permission(){
    	//这个路径填写需要去掉mvc配置的路径
        return new ModelAndView("/permission");
    }
}
    
    
    方法二
   
添加授权拦截器(没用过几次,也不太好用)
filterMap.put("/**", "perms[user:add]");
    
    
    方法三
   
    直接在mvc配置的路径下创建一个error.html页面(名字必须是error)不用任何配置,发生异常时会自动跳转到error页面(所有异常都跳转到这个页面,太宽泛也不太好用)
    
     
   
 
