Reputation: 300
I have an application that will be deployed at two places. There would be one master and one slave. I have a requirement that some of the requests should be satisfied by slave and others by master.
For this, I am sending login request to master on successful login to slave. I am able to achieve this.
My problem is, when i try to access any resource from master(request a resource from master originating from slave) after logging in, It is giving unauthorized(401) error.
Login controller:
$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;
}
}
}]);
My server has a filter
@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");
}
}
Am I missing anything?
Upvotes: 0
Views: 1233
Reputation: 18194
You are incorrectly setting withCredentials
as a request header. This is XHR option and should be present directly on the config:
config.withCredentials = true;
This option will enable cookies for your requests. Your requests will be able to include JSESSIONID
, thus allowing HTTP session where Spring Security stores information about the authentication.
And as discussed in the chat (see question comments) - be aware that if the two servers are running on the same domain, they will share cookies. That might cause issues (sending incorrect JSESSIONID
) so you need to access those servers under different host name.
Upvotes: 2