我有一个将在两个地方部署的应用程序。将有一个主人和一个奴隶。我要求一些请求应由奴隶和其他人由主人满足。
为此,我在成功登录slave时向master发送登录请求。我能够做到这一点。
我的问题是,当我尝试从登录后访问来自主服务器的任何资源(从主服务器请求来自主服务器的资源)后,它会给出未经授权的(401)错误。
登录控制器:
$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");
}
}
我错过了什么吗?
答案 0 :(得分:2)
您错误地将withCredentials
设置为请求标头。这是XHR选项,应直接出现在配置中:
config.withCredentials = true;
此选项将为您的请求启用Cookie。您的请求将能够包含JSESSIONID
,从而允许Spring Security存储有关身份验证的信息的HTTP会话。
正如聊天中所讨论的那样(请参阅问题评论) - 请注意,如果两个服务器在同一个域上运行,they will share cookies。这可能会导致问题(发送错误的JSESSIONID
),因此您需要以不同的主机名访问这些服务器。