无法在 Spring Security 中加载静态内容
Posted
技术标签:
【中文标题】无法在 Spring Security 中加载静态内容【英文标题】:Unable to load static content in spring security 【发布时间】:2019-03-04 03:08:08 【问题描述】:我已经从这个来源构建了一个基本的 spring 身份验证服务: https://spring.io/guides/gs/securing-web/
尝试使用 *** 上的几乎所有解决方案从本地文件夹中包含 JS 文件,但我做不到。当 html 页面加载时,它会说: "Uncaught ReferenceError: myFunction is not defined"
这是我的 home.html 脚本:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Spring Security Example</title>
<script type="javascript" src="test.js"></script>
</head>
<body onload="myFunction()">
<h1>Welcome!</h1>
<p>Click <a href="/hello">here</a> to see a greeting.</p>
</body>
</html>
这是我的 js 文件所在的位置,htmls 放在模板文件夹中。
这是我的 mvcConfig 代码:
package hello;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
@Configuration
public class MvcConfig implements WebMvcConfigurer
public void addViewControllers(ViewControllerRegistry registry)
registry.addViewController("/home").setViewName("home");
registry.addViewController("/").setViewName("home");
registry.addViewController("/hello").setViewName("redirect:http://localhost:3000/home.html");
registry.addViewController("/login").setViewName("login");
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
if (!registry.hasMappingForPattern("/webjars/**"))
registry.addResourceHandler("/webjars/**").addResourceLocations(
"classpath:/META-INF/resources/webjars/");
if (!registry.hasMappingForPattern("/**"))
registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/", "classpath:/resources/","classpath:/static/", "classpath:/public/");
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
WebSecurityConfig 代码:
package hello;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception
http
.authorizeRequests()
.antMatchers("/", "/home","/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
@Bean
@Override
public UserDetailsService userDetailsService()
UserDetails user =
User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
【问题讨论】:
如果文件在不同的文件夹中,test.js 的 src 不仅仅是 test.js。将路径更改为src="../test.js"
可能已经是答案了。
我试过了,但没用..
当我直接在chrome中打开html时,它会正常加载js文件。但是当从应用程序调用该 html 时,它会抛出此错误
【参考方案1】:
无论src/main/resources是什么文件夹,你都可以这样配置,在你的安全配置类中创建这个方法,一般我们把静态资源放在src/main/resources里面的static文件夹中。
//this method allows static resources to be neglected by spring security
@Override
public void configure(WebSecurity web) throws Exception
web
.ignoring()
.antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**","/assets/**","/fonts/**","/dis/**","/vendor1/**");
【讨论】:
你应该使用 websecurity 而不是 httpsecurity ,这个解决方案肯定会起作用-更多你可以看到这个答案 -***.com/a/28272347/7849549 将我的脚本路径更改为: 并更改了我的 WebSecurityConfig 但它不起作用 @AjayKarri 在 src/main/resource 中创建一个静态文件夹,将你所有的 css 放在那里,默认情况下它会查找静态文件夹,所以如果你有 static/js/style.js 你可以写 也删除 -js 之前的斜线 或 脚本> 感谢您的时间和解决方案。我尝试混合您的两种解决方案并进行了更多更改。然后它起作用了:)【参考方案2】:在WebSecurityConfig
类中,您将permitAll 设置为仅'/'
、'/home'
和'/resources/**'
。匿名用户无需安全检查即可访问这三个端点。
对于test.js
文件,src指向当前url中的test.js
。因此,当您在 localhost 上运行它时,浏览器会尝试将 test.js
查找为 http://localhost:port/current-page-url/test.js
例如,如果页面在/home
下,则浏览器调用http://localhost:8080/home/test.js
,但正如您在WebSecurityConfig
中定义的那样,除了/home
本身之外的任何调用都将被Spring Security 阻止。 (/home
和/home/**
不一样)
所以你需要做的是将src url更改为<script src="/resources/test.js"></script>
因为/resources/**
端点下的任何东西都可以被任何人访问并且它已经在MvcConfig
的resourceHandler配置中注册
registry.addResourceHandler("/resources/**")
.addResourceLocations("classpath:/");
希望这会有所帮助!快乐编码:)
添加:
此外,在<script>
标记中,您应该将type
属性更改为text/javascript
,或者您可以删除该属性,它会起作用。
【讨论】:
我已经尝试过这个解决方案,但没有成功。让我再试一次并确认 别忘了在开头加上/
指向类路径
不工作.. 它说:Whitelabel 错误页面
此应用程序没有明确的 /error 映射,因此您将其视为后备。
2018 年 9 月 28 日星期五 12:58:49 IST 2018 出现意外错误(类型=内部服务器错误,状态=500)。模板解析时出错(模板:“类路径资源 [templates/home.html]”- 第 5 行,第 3 列)跨度> Ajay 如果test.js
文件在资源文件夹中,那么您应该将 resourceLocation 指向 .addResourceLocations("classpath:/")
或者正如 Jai 所提到的,您可以将所有静态文件放在 /resources/static 文件夹中来组织它们和.addResourceLocations("classpath:/static")
谢谢 koo.. 更新这个已经解决了我一半的问题。 registry.addResourceHandler("/**") .addResourceLocations("classpath:/");以上是关于无法在 Spring Security 中加载静态内容的主要内容,如果未能解决你的问题,请参考以下文章
Spring,无法在测试中加载 ApplicationContext
spring - @ContextConfiguration 无法在 src/test/resources 中加载配置文件