146. Spring Boot Shiro cannot access JS/CSS/IMG + custom Filter cannot access the perfect solution [Learn Spring Boot from scratch]

 

【Video & Communication Platform】

à SpringBoot Video 

http://study.163.com/course/introduction.htm?courseId=1004329008&utm_campaign=commission&utm_source=400000000155061&utm_medium=share

à  SpringCloud video

http://study.163.com/course/introduction.htm?courseId=1004638001&utm_campaign=commission&utm_source=400000000155061&utm_medium=share

à Spring Boot source code 

https://gitee.com/happyangellxq520/spring-boot

à Spring Boot communication platform 

http://412887952-qq-com.iteye.com/blog/2321532

 

  

     Today , September 10 , 2017 , is Teachers' Day. I would like to thank the teachers and wish them a happy holiday. I have met several teachers in my student life who have been especially good to me, and I really appreciate them, because of you, we have grown .

Origin of need :

       Some netizens said: JS/CSS/IMG cannot be accessed . In fact, this problem is particularly easy to solve for those who have used Shiro . You only need to do a simple configuration. But if you don't know Shiro , you may need help. . Haha, if you answer the same question too many times, your ears will grow calluses. Well, this blog is to solve this problem.

 

( 1 ) JS/CSS/IMG is intercepted by shiro

       The static resources we requested for spring boot were intercepted by the shiro filter, so I think I can let shiro release it directly, that is, css:anno , img:anno , js:anno , the conversion to shiro code is:

 

 

ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean ();
filterChainDefinitionMap.put("/img/**", "anon");//img       
filterChainDefinitionMap.put("/js/**", "anon");//js
filterChainDefinitionMap.put("/css/**", "anon");//css
 

 

 

 

2)自定义Filter导致无法访问

       如果添加了上面的配置,还无法使用的,那么就看看是否是如下这种情况引起的:

ShiroConfiguration中如果您有这么一段自定义Filter的代码:

 

    @Bean
    public CustomFormAuthenticationFilter formAuthenticationFilter(){
       CustomFormAuthenticationFilter customFormAuthenticationFilter = new CustomFormAuthenticationFilter();
       return customFormAuthenticationFilter;
    }
 

 

       这样注入Filter的方式也是会出现JS/CSS/IMG无法访问的,这是为什么呢?

这是因为:容器把自定义的CustomFormAuthenticationFilter也作为容器的filter接管,所有的请求又都经过一次filter,那么就会导致一个问题出现:比如:我们定义 /js/**=anon,/css/**=anon, /img/ =anno,那么所有JS/CSS/IMG等资源文件也会被拦截。也就是说:我们自定义的CustomFormAuthenticationFiltershiroFilter不再是上下级的关系了,而是平级的关系,由SpringApplicationFilterConfig一起管理了。

       那也就是说:我们只需要修改为上下级的关系就可以了。

首先,我们就不能CustomFormAuthenticationFilterSpring管理了,先去掉注解@Bean

       第二就是:使用ShiroFilterFactoryBean进行注入,就是上下级的关系了,核心代码部分:

 

     

ShiroFilterFactoryBean shiroFilterFactoryBean  = new ShiroFilterFactoryBean();
//自定义filter.
Map<String,Filter> filters  = new HashMap<String,Filter>();
CustomFormAuthenticationFilter formAuthenticationFilter =  new CustomFormAuthenticationFilter();//初始化自定义的filter.
filters.put("authc", formAuthenticationFilter);//添加到map中.
shiroFilterFactoryBean.setFilters(filters);//交给spring shiroFilter管理

 

 

 

3)问题2方案导致新问题

       我们使用了new CustomFormAuthenticationFilter()的方式就无法使用spring的特性,在CustomFormAuthenticationFilter的类中就不能使用@Autowire注入别的service进行使用了。所以这里就存在了新的问题了,由不能直接使用@Bean的方式注入,那么怎么解决呢?

       我们会思考是否有一种方式注册我们自定义的FilterSpring容器中,但是又不添加FilterFilterChain中呢?所以我们的问题也就是:怎么取消    Filter自动注册?

       Spring BootFilterServlet提供了相应的注册类,来进行精细化的配置,我们可以使用注册类来取消Filter的自动注册。通过使用FilterRegistrationBean来进行Filter的注册,同时,设置enabledfalse,就可以取消Filter的自动注册行为了。可以参考文档:Spring Boot Document

       具体怎么操作呢?

    @Bean
    public CustomFormAuthenticationFilter customFormAuthenticationFilter(){
       System.out.println("ShiroConfiguration.formAuthenticationFilter()");
       CustomFormAuthenticationFilter customFormAuthenticationFilter = new CustomFormAuthenticationFilter();
       return customFormAuthenticationFilter;
    }
 
    @Bean
    public FilterRegistrationBean registrationBean(CustomFormAuthenticationFilter customFormAuthenticationFilter){
       System.out.println("AppcustomFormAuthenticationFilter()");
       FilterRegistrationBean registration = new FilterRegistrationBean(customFormAuthenticationFilter);
        registration.setEnabled(false);//怎么取消  Filter自动注册,不会添加到FilterChain中.
        return registration;
    }

 

       这里还是使用@Bean注入CustomFormAuthenticationFilter,但是在自动注入之后使用FilterRegistrationBean对其重新进行了设置,取消自动注册功能。这里容易犯错的地方就是CustomFormAuthenticationFilter不使用@Bean注入了,如果是这样的话,就会发现是先shiro的配置先注入,CustomFormAuthenticationFilter还没注入就无法找到了。

 

视频&交流平台

à SpringBoot网易云课堂视频

http://study.163.com/course/introduction.htm?courseId=1004329008

à Spring Boot交流平台

http://412887952-qq-com.iteye.com/blog/2321532

 

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326850949&siteId=291194637