在开发模式下运行时,Spring Security发生配置问题,导致React前端(使用React路由器运行)上的登录页面重新定向。我相信重定向不会被我的前端所接受,这是因为我没有理解服务器端路由如何与SPA路由交互。Spring Security登录页面与SPA中的React Router重定向
我的开发前端Web服务器(使用Facebook创建React应用程序)在localhost:3000上运行,我的后端Spring Boot Tomcat在localhost:8080上运行。我已经启用了Spring Security,它可以在Tomcat服务器(端口8080)上正常工作;访问本地主机:8080转发到本地主机:8080 /登录。在访问localhost:3000时,我得到了一个交叉错误,因此在here中增加了对Spring的CORS支持。我也咨询了this Spring博文。它似乎工作,因为我不再得到交叉原点错误。然而,虽然没有登陆,从本地主机请求:3000为localhost:8080 /登录返回如下:
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>
...
这是我的前端Web服务器中的index.html主持。这很好,但我需要它转发到本地主机:3000 /登录,这将呈现登录页面index.html。
我相信它不会转发到/登录,因为路由设置的,它会从localhost:3000/
- >HttpSecurity.loginPage("/login")
(春季) - >registry.addViewController("/login").setViewName("forward:/index.html")
(春季) - ><Route path="/" component={ForwardToLandingPage} />
(阵营路由器)
它出错的结束。我希望Tomcat服务器将前端重新指向:3000/login,但前端转到该组件。似乎服务器端重定向和前端React路由器之间存在问题。如果这太复杂了,我可能会把这整个Spring Security放到我的开发环境中。
这里是我的配置:
阵营路由配置
ReactDOM.render((
<Router history={browserHistory}>
<Route path="/" component={ForwardToLandingPage} />
<Route path="/login" component={Login} />
</Router>
),
document.getElementById('root')
);
Spring MVC的配置
@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");
}
}
春CORS配置
@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;
}
}
春季安全配置
@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了。
感谢您的帮助! :)
你可以发布一个链接到Facebook创建React应用程序,它是否发出ajax请求或常规http请求? –
'localhost:8080/login'是登录页面吗? – chaoluo
感谢您的问题。我今天一直在做更多的尝试,我现在认为这个问题更多的是在我的后端和前端之间进行路由和重定向。我用我的发现和配置更新了我的问题。另外我应该补充一点,我遇到的问题是当我在我的开发环境中。直接访问端口8080或托管的AWS Elastic Beanstalk时,所有服务(包括前端)内容均可正常工作。如果修复太复杂,我只会在开发环境中禁用登录。 – Jannik