我有这个要求,我从localhost:8000调用角度应用程序的跨域ajax调用 . [我正在使用连接的grunt:启动Web服务器的livereload]
角度路由localhost:8000 / user / login显示一个表单登录,其提交对与Spring安全集成的后端Spring Rest Controller进行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() {
}
有了这些类,我希望我的 endpoints /登录时的RestController能够提供硬编码的json字符串 .
我在CORSFilter中有@ Ordered.HIGHEST_PRECEDENCE注释,它应该确保在SpringSecurityConfig之前加载CORSFilter . CORSFilter和SpringSecurityConfig都在同一个包中 . 我让他们通过RootConfig进行“组件扫描” . 因此,我可以说它们应该作为SAME WebApp上下文的一部分提供 .
我的firefox网络控制台向/ login显示“OPTIONS”请求,状态为200 OK . 但控制台显示警告:
跨源请求已阻止:同源策略不允许在http://localhost:8080/mynext-app/login读取远程资源 . (原因:CORS Headers 'Access-Control-Allow-Origin'缺失) .
请求 Headers :
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
我能想到的唯一缺失的信息,就是这个“拼图游戏”或许是Tomcat 7的CORSFilter . 我不确定这是否也需要实施 .
我知道浏览器通过OPTIONS调用发送其“预检”请求 . 我似乎没有得到,是响应是200 OK,但尽管控制台显示CORS警告 . 在这里,我希望在OPTIONS HTTP方法调用之后使用POST显示json字符串 .
我在这里失踪的是什么任何指针都非常感谢 .
更新(03/11/2015) - 我在Spring中缺少这个配置:
@Override
protected Filter[] getServletFilters() {
return new Filter[] { new CorsFilter() };
}
有了这个,我得到一个后续的POST调用/ login POST,但是这有一些很长的Spring-Security异常 .
我尝试使用Tomcat CORSFilter,但是我需要为我控制CSRF的Spring CORS . 我已经和Tomcat一起工作了很长时间,因为我有机会去做,但不是真的 .
接下来我会尝试使用Angular $ http而不是$ ajax并使用Spring安全推荐的资源编程 . 也许这就是解决方案 .
谢谢,