一文解决Security中访问静态资源和web.ignoring()和perimitAll()不起作用

2022-07-03 14:35:26
本文参考

【1】江南一点雨的SpringSecurity配置
【2】WebMvcConfiguer配置

问题需求

学习微人事项目中,我想在后端加入静态资源,我的静态资源就在static目录下,可怎么配置都返回需要权限认证,调试后发现,如下代码访问的所有路径,都会进到FilterInvocationSecurityMetadataSource中进行处理,松哥原话

getAttributes(Object o)方法返回null的话,意味着当前这个请求不需要任何角色就能访问,甚至不需要登录

在这里插入图片描述
代码可修改如下(初始版本),后有通用解决方案

@ComponentpublicclassCusomFilterIncovationSecurityMetadataSourceimplementsFilterInvocationSecurityMetadataSource{@Autowired
    MenuService menuService;// ant路径匹配的类
    AntPathMatcher antPathMatcher=newAntPathMatcher();@Overridepublic Collection<ConfigAttribute>getAttributes(Object o)throws IllegalArgumentException{
        String requestUrl=((FilterInvocation) o).getRequestUrl();
        List<Menu> menus= menuService.getAllMenusRole();
        System.out.println("开始匹配路径");for(Menu menu: menus){if(antPathMatcher.match(menu.getUrl(), requestUrl)){
                List<Role> roles= menu.getRoles();
                String[] str=newString[roles.size()];for(int i=0; i<roles.size();i++){
                    str[i]= roles.get(i).getName();}return SecurityConfig.createList(str);}}//静态资源配置,返回null表示不要任何角色即可访问for(String url: StaticSource.source){//System.out.println(url);//System.out.println(requestUrl);if(antPathMatcher.match(url,requestUrl)){return null;}}// 标记而已return SecurityConfig.createList("ROLE_LOGIN");}@Override// 不用管public Collection<ConfigAttribute>getAllConfigAttributes(){return null;}@Overridepublicbooleansupports(Class<?> aClass){returntrue;}}
@ComponentpublicclassCustomUrlDecisionManagerimplementsAccessDecisionManager{@Override/**
     * @param:
     * authentication 用户登陆信息
     * collection Filter的返回值
     */publicvoiddecide(Authentication authentication, Object o, Collection<ConfigAttribute> collection)throws AccessDeniedException, InsufficientAuthenticationException{//System.out.println(collection.size());//System.out.println(collection);// 修改内容if(collection== null|| collection.isEmpty()){return;}for(ConfigAttribute configAttribute: collection){
            String needRole= configAttribute.getAttribute();if("ROLE_LOGIN".equals(needRole)){// 判断用户是否登陆if(authenticationinstanceofAnonymousAuthenticationToken){thrownewAccessDeniedException("尚未登陆,请登陆");}else{return;}}
            Collection<?extendsGrantedAuthority>authorities= authentication.getAuthorities();// A,B两个角色有一个即可访问for(GrantedAuthority authority:authorities){// 匹配到角色,立刻返回if(authority.getAuthority().equals(needRole)){return;}}}thrownewAccessDeniedException("权限不足,请联系管理员");}@Overridepublicbooleansupports(ConfigAttribute configAttribute){returntrue;}@Overridepublicbooleansupports(Class<?> aClass){returntrue;}}
publicclassStaticSource{publicstaticfinal String[] source=newString[]{"/img/**","/js/**","/css/**","/favicon.ico"};}
通用解决
// 不起作用的配置@Overridepublicvoidconfigure(WebSecurity web)throws Exception{
     web.ignoring().antMatchers("/img/**");}protectedvoidconfigure(HttpSecurity http)throws Exception{
 	http.authorizeRequests().antMatchers("/img/**").permitAll()}

根据参考资料【2】的描述,在SpringBoot2.0中WebMvcConfigurerAdapter已被废弃,访问静态资源就会被HandlerInterceptor拦截,为了防止静态资源被拦截,我们需要实现自己的inteceptor的规则

通用解决方案:

// 创建自己的拦截器类,实现HandlerInterceptor 接口publicclassMyInterceptorimplementsHandlerInterceptor{}
@ConfigurationpublicclassMyWebMvcConfigurerimplementsWebMvcConfigurer{@OverridepublicvoidaddInterceptors(InterceptorRegistry registry){
        registry.addInterceptor(newMyInterceptor()).addPathPatterns("/**").excludePathPatterns("/swagger-ui.html","/js/**","/css/**","/img/**");}}
  • 作者:优雅一只猫
  • 原文链接:https://blog.csdn.net/weixin_41492426/article/details/105162636
    更新时间:2022-07-03 14:35:26