sadhvaryu
sadhvaryu

Reputation: 300

CORS issue angularjs and spring security

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

Answers (1)

Pavel Horal
Pavel Horal

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

Related Questions