CORS问题angularjs和spring security
我有一个将在两个地方部署的应用程序。会有一个主人和一个奴隶。我有一个要求,有些要求应该由奴隶来满足,有些要求应该由主人来满足 为此,我将在成功登录到从属服务器时向主服务器发送登录请求。我能够做到这一点 我的问题是,当我在登录后尝试从主服务器访问任何资源(从从从服务器请求主服务器的资源)时,它给出了未经授权的(401)错误 登录控制器:CORS问题angularjs和spring security,angularjs,spring,cors,Angularjs,Spring,Cors,我有一个将在两个地方部署的应用程序。会有一个主人和一个奴隶。我有一个要求,有些要求应该由奴隶来满足,有些要求应该由主人来满足 为此,我将在成功登录到从属服务器时向主服务器发送登录请求。我能够做到这一点 我的问题是,当我在登录后尝试从主服务器访问任何资源(从从从服务器请求主服务器的资源)时,它给出了未经授权的(401)错误 登录控制器: $http.post('j_spring_security_check', payload, config).success(function(data, t
$http.post('j_spring_security_check', payload, config).success(function(data, textStatus, jqXHR, dataType) {
if ($scope.rememberme) {
var user = {
username: $scope.username,
password: $rootScope.encryptPass($scope.password, true),
rememberme: $scope.rememberme
};
localStorage.setItem('user', JSON.stringify(user));
} else {
localStorage.removeItem('user');
}
$rootScope.pingServer();
$rootScope.retrieveNotificationCount();
$http.post('http://localhost:9090/context/j_spring_security_check',payload, config).success(function(data, textStatus, jqXHR, dataType) {
$rootScope.pingServer();
}).error(function(data, status, headers, config) {
});
});
app.js
rootapp.config(['$httpProvider', function(httpProvider) {
httpProvider.interceptors.push(['$rootScope', function($rootScope) {
return {
request: function(config) {
config.headers = config.headers||{};
config.headers['withCredentials'] = true;
config.headers['useXDomain'] = true;
return config;
}
}
}]);
我的服务器有一个过滤器
@Singleton
public class ResponseCorsFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
if (servletResponse instanceof HttpServletResponse) {
if (request.getMethod().equals("OPTION") || request.getMethod().equals("OPTIONS")) {
System.out.println("In Options");
if (request.getServletPath().equals("/j_spring_security_check")) {
System.out.println("request path match");
alteredResponse.setStatus(HttpServletResponse.SC_OK);
addHeadersFor200Response(alteredResponse);
return;
}
}
addHeadersFor200Response(alteredResponse);
}
filterChain.doFilter(servletRequest, servletResponse);
}
private void addHeadersFor200Response(HttpServletResponse response) {
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addHeader("Access-Control-Allow-Methods", "ACL, CANCELUPLOAD, CHECKIN, CHECKOUT, COPY, DELETE, GET, HEAD, LOCK, MKCALENDAR, MKCOL, MOVE, OPTIONS, POST, PROPFIND, PROPPATCH, PUT, REPORT, SEARCH, UNCHECKOUT, UNLOCK, UPDATE, VERSION-CONTROL");
response.addHeader("Access-Control-Allow-Headers", "useXDomain, withCredentials, Overwrite, Destination, Content-Type, Depth, User-Agent, Translate, Range, Content-Range, Timeout, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Location, Lock-Token, If");
response.addHeader("Access-Control-Expose-Headers", "DAV, content-length, Allow");
response.addHeader("Access-Control-Max-Age", "86400");
}
}
我遗漏了什么吗?您错误地将带有凭据的
设置为请求头。这是XHR选项,应该直接出现在配置中:
config.withCredentials = true;
此选项将为您的请求启用Cookie。您的请求将能够包括JSESSIONID
,从而允许HTTP会话,其中Spring安全性存储有关身份验证的信息
正如聊天中所讨论的(请参阅问题注释)-请注意,如果两台服务器在同一个域上运行。这可能会导致问题(发送不正确的JSESSIONID
),因此您需要以不同的主机名访问这些服务器。您是否对一台服务器进行身份验证,然后尝试向另一台服务器发出未经身份验证的请求?如果是这样,那么你得到401也就不足为奇了。与CORS无关。我正在两台服务器上进行身份验证。它工作正常。我的问题是,一旦身份验证完成,当我从master请求资源时,我会得到401。我是否需要将我的凭据与初始身份验证后的请求一起发送?如果是,我该如何发送?我知道你的错误<代码>withCredentials
不是标题,而是XHR选项-。如果没有此选项,跨源请求不包含Cookie。不withCredentials
通常会启用Cookie。因此,您的请求将能够包含JSESSIONID
——从而允许HTTP会话,其中Spring Security存储有关身份验证的信息。只需添加config.withCredentials=true
,而不是将其设置为标题。