我遇到配置问题,当在开发模式下运行时,Spring Security会重定向到我的React前端的登录页面(与React Router一起运行) . 我相信重定向不会被我的前端接收,这是由于我对服务器端路由如何与SPA路由交互的理解 .
我的开发前端Web服务器(使用Facebook Create React App)在localhost:3000上运行,我的后端Spring Boot Tomcat在localhost:8080上运行 . 我启用了Spring Security,它在Tomcat服务器上工作正常(端口8080);访问localhost:8080转发到localhost:8080 / login . 访问localhost:3000时,我遇到了跨源错误,因此在Spring中添加了CORS支持,如here所述 . 我也咨询过this Spring 季博客文章 . 它似乎有效,因为我不再得到跨源错误 . 但是,在未登录的情况下,localhost:3000到localhost:8080 / login的请求将返回以下内容:
HTTP/1.1 200 OK
X-Powered-By: Express
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=UTF-8
Content-Length: 1496
ETag: W/"5d8-80rXYG+kNfQ/xEJ7J2f1PA"
Vary: Accept-Encoding
Date: Tue, 10 Jan 2017 12:04:07 GMT
Connection: keep-alive
<!DOCTYPE html>
...
这是我的前端网络服务器中托管的index.html . 这很好,但我需要它转发到localhost:3000 / login,这会将登录页面呈现为index.html .
我相信它不会转发到/ login因为路由设置,它来自 localhost:3000/
- > HttpSecurity.loginPage("/login")
(Spring) - > registry.addViewController("/login").setViewName("forward:/index.html")
(Spring) - > <Route path="/" component={ForwardToLandingPage} />
(React Router)
最后它出了问题 . 我希望Tomcat服务器将前端重定向到:3000 / login,而前端则转到组件 . 似乎服务器端重定向和前端React Router到达正确位置之间存在问题 . 如果这太复杂而无法设置,我可能会将整个Spring Security放在我的开发环境中 .
这是我的配置:
React routing config
ReactDOM.render((
<Router history={browserHistory}>
<Route path="/" component={ForwardToLandingPage} />
<Route path="/login" component={Login} />
</Router>
),
document.getElementById('root')
);
Spring MVC config
@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// This forwarding is required, as my React app is rendering on a div
// element with the ID 'root' in /index.html. But is this part of the
// problem?
registry.addViewController("/").setViewName("forward:/index.html");
registry.addViewController("/login").setViewName("forward:/index.html");
}
}
Spring CORS config
@Configuration
public class MyConfiguration {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://localhost:3000");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
Spring Security config
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable() // temporary fix
.authorizeRequests()
.antMatchers("/h2-console", "/public/**", "/static/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
}
}
有什么想法会出错吗?
我想知道问题的解决方案是否应该涉及Tomcat,所以也检查了this .
谢谢你的帮助! :)
1 回答
我们使用的是旧版本的Spring安全性,我不知道它是否支持CORS . 我使用Spring安全性已有6年了,所以我只创建了一个常规过滤器:
并在ChannelProcessingFilter之前添加,因此它成为过滤器链中的第一个过滤器 .
如果这对您不起作用,那么我不确定它只是一个CORS问题 .