我有这个要求,我从localhost:8000调用角度应用程序的跨域ajax调用。 [我正在使用连接的grunt:启动网络服务器的livereload]
angular route localhost:8000 / user / login显示一个表单登录,其提交对后端Spring Rest Controller与Spring安全性集成进行ajax调用。应用程序托管在localhost:8080 / mynext-app / login
在angular指令中调用AJAX:mynextapp-login.validate.js:
angular.module('login').directive('loginvalidate', function() {
//jquery.validate.js settings in between.
// followed by its handler
submitHandler: function(form) {
var email = $("#email").val();
var password = $("#pwd").val();
var request = $.ajax({
url: "http://localhost:8080/mynext-app/login",
method: "POST",
contentType: "application/json",
crossDomain:true,
data: { email: email, password: password },
dataType: "json"
});
我的LoginController:
包com.mynext.mynextapp.config;
@RestController
public class LoginController {
@RequestMapping(value="/login", method=RequestMethod.POST, produces="application/json")
public ResponseEntity<?> doLogin() {
return new ResponseEntity<>("{\"code\":\"1\",\"msg\":\"Login Successfully\",\"redirect\":\"http://localhost:9001/\"}", HttpStatus.OK);
}
}
我使用的是所有Java,没有WEB.XML配置:
WebConfig:
@Configuration
@EnableWebMvc
@ComponentScan({"com.mynext.mynextapp.web"})
public class WebConfig extends WebMvcConfigurerAdapter {
}
RootConfig:
@Configuration
@ComponentScan(basePackages={"com.mynext.mynextapp"},
excludeFilters={
@Filter(type=FilterType.CUSTOM, value=WebPackage.class)
})
public class RootConfig {
public static class WebPackage extends RegexPatternTypeFilter {
public WebPackage() {
super(Pattern.compile("com\\.mynext\\.mynextapp\\.web"));
}
}
}
SpringSecurityConfig:
我只是使用表单登录,没有HTTP Basic,禁用。
@Configuration
@EnableWebMvcSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("thisismyemailid@gmail.com")
.password("aaa")
.roles("CLIENT", "SERVICEPROV");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/login")
.usernameParameter("email")
//.and()
//.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/")
.authenticated()
.anyRequest()
.permitAll()
.and()
.csrf()
.disable();
}
}
CORSFilter
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
class CorsFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
try {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
response.setHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(req, res);
} catch (Exception e) {
e.printStackTrace();
}
}
public void init(FilterConfig filterConfig) {
}
public void destroy() {
}
有了这些类,我希望我的端点/登录时的RestController能够提供硬编码的json字符串。
我的CORSFilter中有@ Ordered.HIGHEST_PRECEDENCE注释,它应该确保在SpringSecurityConfig之前加载CORSFilter。 CORSFilter和SpringSecurityConfig都在同一个包中。我有他们&#34;组件扫描&#34;通过RootConfig。因此,我可以说它们应该作为SAME WebApp上下文的一部分提供。
我的firefox的网络控制台显示了一个&#34; OPTIONS&#34;请求/登录状态200 OK。但是Console显示警告:
阻止跨源请求:同源策略禁止在http://localhost:8080/mynext-app/login读取远程资源。 (原因:CORS标题&#39; Access-Control-Allow-Origin&#39;缺失)。
请求标题:
Accept
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding
gzip, deflate
Accept-Language
en-US,en;q=0.5
Access-Control-Request-He...
content-type
Access-Control-Request-Me...
POST
Cache-Control
no-cache
Connection
keep-alive
Host
localhost:8080
Origin
http://localhost:8000
Pragma
no-cache
User-Agent
Mozilla/5.0 (Windows NT 6.3; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0
我能想到的唯一缺失的信息,这个&#34;拼图游戏&#34;也许是Tomcat 7的CORSFilter。我不确定这是否也需要实施。
我确实知道浏览器会发送&#34;预检&#34;请求OPTIONS调用。我似乎没有得到的,是响应是200 OK,但是尽管控制台显示了CORS警告。在这里,我希望在OPTIONS HTTP方法调用之后使用POST显示json字符串。
我在这里失踪的是什么。任何指示都非常感谢。
更新(2015年11月3日) - 我在Spring中错过了这个配置:
@Override
protected Filter[] getServletFilters() {
return new Filter[] { new CorsFilter() };
}
有了这个,我得到了对/ login POST的后续POST调用,但是这会遇到一些很长的Spring-Security异常。
我尝试使用Tomcat CORSFilter,但是我需要为我控制CSRF的Spring CORS。我已经和Tomcat一起工作了很长时间,因为我有机会去做,但不是真的。
接下来我会尝试使用Angular $ http而不是$ ajax并使用Spring安全推荐的资源编程。可能就是解决方案。
谢谢,