Springboot+Shiro配置setUnauthorizedUrl()不生效

  • Post author:
  • Post category:其他




问题背景

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页面(所有异常都跳转到这个页面,太宽泛也不太好用)

请添加图片描述



版权声明:本文为weixin_45864962原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。