不登录就无法访问静态资源目录(我使用的是spring security)

Posted

技术标签:

【中文标题】不登录就无法访问静态资源目录(我使用的是spring security)【英文标题】:Not able to access static resources directory without logging in(I am using spring security) 【发布时间】:2021-11-18 08:36:41 【问题描述】:

问题:我无法访问位于 spring boot 项目的默认资源文件夹下的静态资源,例如图像、js 或 css 文件。我正在使用 Spring Boot 版本(2.4.9)。现在,经过大量研究,我想出了一个我在 spring doc 网站上找到的解决方案,即使用以下代码:

.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()

现在有趣的是,使用这段代码后,我仍然无法访问资源文件夹下的任何文件或文件夹,但我可以访问名为 images 的文件夹(我做到了) 在资源文件夹下。任何解决方案或有用的提示?

我的项目的目录结构:

screenshot of project directory

安全配置文件:

package com.pisoft.informatics.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class DemoSecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
     
    //bcrypt bean definition
    /*
    @Bean
    public BCryptPasswordEncoder passwordEncoder() 
        return new BCryptPasswordEncoder();
    
    */
      
    @Autowired
    private MeriCustomAuthenticationProvider authProvider;
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        //auth.authenticationProvider(authenticationProvider());
        auth.authenticationProvider(authProvider);
    
        
    @Override
    protected void configure(HttpSecurity http) throws Exception 
        
        http.authorizeRequests()    
            //.antMatchers("/resources/**").permitAll()         
            .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()           
            .anyRequest().authenticated()           
            
            .and()
            .formLogin()                
                .loginPage("/")
                .loginProcessingUrl("/authenticateTheUser")
                .successHandler(customAuthenticationSuccessHandler)
                .permitAll()
            .and()
            .logout()
            .permitAll()
                    
            .and()
            .csrf().disable();  
    

CustomAuthenticationProvider 文件:

package com.pisoft.informatics.security;

import java.util.ArrayList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
import com.pisoft.informatics.entity.user.CrmUser;
import com.pisoft.informatics.misc.EncryptionUtil1;
import com.pisoft.informatics.service.user.CrmUserService;



@Component
public class MeriCustomAuthenticationProvider implements AuthenticationProvider

    @Autowired
    private CrmUserService userService;
    
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException 
        
        String name = authentication.getName();
        String password = authentication.getCredentials().toString();
        
        //System.out.println("name :"+name+" password :"+password);
        
            // use the credentials
            CrmUser user= userService.findByUserName(name);
            if(user!=null) 
                if(password.equalsIgnoreCase(EncryptionUtil1.decode(user.getPassword()))) 
                    if(user.getStatus().equalsIgnoreCase("Active")) 
                        return new UsernamePasswordAuthenticationToken(name, password, new ArrayList<>());
                    
                    else 
                        return null;
                    
                
                else 
                    return null;
                
            
            else 
                return null;
                               
    

    @Override
    public boolean supports(Class<?> authentication) 
        
         return authentication.equals(UsernamePasswordAuthenticationToken.class);
       

SecurityWebApplicationInitializer 文件:

package com.pisoft.informatics.security;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer


CustomAuthenticationSuccessHandler 文件:

package com.pisoft.informatics.security;


import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import com.pisoft.informatics.misc.*;
import com.pisoft.informatics.entity.user.CrmUser;
import com.pisoft.informatics.service.sidebar.ServiceHeader;
import com.pisoft.informatics.service.user.CrmUserService;

@Component
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler 

    @Autowired
    private CrmUserService crmUserService;
   
    @Autowired
    private ServiceHeader headerService;
    
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException 
        
        String userName = authentication.getName();
        CrmUser theUser = crmUserService.findByUserName(userName);
        
        // now place in the session
        HttpSession session = request.getSession();
        session.setAttribute("CRMUserDetails", theUser);
        session.setAttribute("allMenus", headerService.getMeAllMainMenus());
        session.setAttribute("greetings", WishUtill.Wish());
        // forward to home page
        
        response.sendRedirect(request.getContextPath() + "/dashboard");
    


【问题讨论】:

尝试访问静态资源时遇到什么异常? 【参考方案1】:

/static 下有很多目录与PathRequest.toStaticResources().atCommonLocations() 不匹配。匹配以下位置:/static/css/**、/static/js/**、/static/images/**、/static/webjars/**、/static/favicon.* 和 /static/* /图标-*。这就是为什么您的图像可以访问的原因。您需要使用 permitAll() 为您的自定义位置添加 antMatchers(例如 antMatchers("/build/**", "/delete-popup/**", ...).permitAll()

【讨论】:

非常感谢,它就像一个魅力。

以上是关于不登录就无法访问静态资源目录(我使用的是spring security)的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot静态资源无法访问

SpringBoot静态资源无法访问

springboot + thymeleaf静态资源访问404

SpringBoot实现静态资源映射,登录功能以及访问拦截验证——以黑马瑞吉外卖为例

spring boot项目进行war部署,对于静态资源无法访问的问题

项目一众筹网08_02_SpringSecurity放行登录页和静态资源内存版登录和退出登录