Spring Security and Angular js basic authentication not working - angularjs

I am trying to build a simple application in angular-js and spring security.I am using basic authentication.Whenever browsing home page ,i am getting basic authentication pop-up for user name password.If i cancel it and login with correct password,application is working fine.But if i enter wrong password the same basic authentication pop -up is coming.I am sending X-Requested-With header in every request and it is visible in header fiends also.Any one has any idea,what's going wrong here?
Angular :
'use strict';
var todoApp=angular.module('todoApp',['ngRoute']);
todoApp.config(['$routeProvider','$httpProvider',function($routeProvider,$httpProvider){
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
$routeProvider.when('/',{
templateUrl:'resources/templates/Home.html',
controller:'HomeController'
}).otherwise({redirectTo:'/'});
}]);
'user strict';
todoApp.controller('NavBarController',function($rootScope, $scope, $http, $location, $route){
$scope.credentials = {};
$scope.login = function() {
authenticate($scope.credentials, function(authenticated) {
if (authenticated) {
console.log("Login succeeded")
$location.path("/");
$scope.error = false;
$rootScope.authenticated = true;
} else {
console.log("Login failed")
$location.path("/");
$scope.error = true;
$rootScope.authenticated = false;
}
})
};
$scope.logout=function(){
$http.post('logout', {}).success(function() {
$rootScope.authenticated = false;
$location.path("/");
}).error(function(data) {
console.log("Logout failed")
$rootScope.authenticated = false;
});
}
var authenticate=function(credentials,callback){
//create headers for request
var headers= credentials? {
authorization:"Basic "
+btoa(credentials.username+":"+credentials.password)}:{};
//request to http basic service
$http.get('user/authenticate',{
headers:headers
}).success(function(data){
if(data.name){
$rootScope.authenticated=true
}else{
$rootScope.authenticated=false;
}
callback && callback($rootScope.authenticated);
}).error(function(data){
$rootScope.authenticated=false;
callback && callback(false);
});
};
authenticate();
});
security configuration:
<sec:http use-expressions="true">
<sec:intercept-url pattern="/" access="permitAll"/>
<sec:intercept-url pattern="/index.html" access="permitAll"/>
<sec:intercept-url pattern="/Home.html" access="permitAll"/>
<sec:intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
<sec:http-basic/>
</sec:http>
<sec:authentication-manager>
<sec:authentication-provider>
<sec:jdbc-user-service data-source-ref="dataSource" id="userDetailsService"/>
</sec:authentication-provider>
</sec:authentication-manager>
Headers:
Content-Language:en
Content-Length:1160
Content-Type:text/html;charset=utf-8
Date:Fri, 12 Jun 2015 02:46:18 GMT
Server:Apache-Coyote/1.1
WWW-Authenticate:Basic realm="Spring Security Application"
Request Headers
view source
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Cookie:JSESSIONID=A06CEC616C9A34B915EA298A890C5E80
Host:localhost:9999
Pragma:no-cache
Referer:http://localhost:9999/todoapp/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36
X-Requested-With:XMLHttpRequest

Sending WWW-Authenticate:Basic realm="Spring Security Application" will cause the browser to show a login form.
You need to serve your initial angular assets without requiring Basic authentication.

Related

unsupported Media type 415 for file upload with Spring mvc restcontroller and angularjs

When i am trying to hit the angularjs $http.post which contains file upload details its giving me unsupported media type. I am using backend spring mvc rest controller. The following is the code snippet.
<ul><li><h4>Document Type</h4>
<select name="docType" ng-model="docType" name="docType">
<option value="Report1">Report1</option>
<option value="Report2">Report2</option>
</select>
<input type="file" ng-model-instant id="fileToUpload" onchange="angular.element(this).scope().setFiles(this)" />
</li>
<li><h4>Comments:</h4><textarea></textarea></li>
<li><button class="btn-panel-blue" type="submit">Saves</button></li>
<li>Cancel</li>
</ul>
angular.module('app')
.controller('prjCntrl', function ($scope,projectService, sharedService, $location, $log, $http, $state) {
$scope.setFiles = function(element) {
$scope.$apply(function(scope) {
$scope.uploadedFile ;
for (var i = 0; i < element.files.length; i++) {
$scope.uploadedFile=element.files[i];
break;
}
});
};
$scope.updateProject = function updateProject()
{
var formData=new FormData();
formData.append('docType',angular.toJson($scope.projectData.docType,true));
formData.append("uploadFile",$scope.uploadedFile);
var url=baseURL + '/updateProject.do';
$http.post(url, formData, { transformRequest: angular.identity, headers: {'Content-Type': undefined} })
.success(function(){alert("success");})
.error(function(){ });
};
}
);
and here is my java code.
#RestController
#MultipartConfig(fileSizeThreshold=1024*1024*10,
maxFileSize=1024*1024*50,
maxRequestSize=1024*1024*100)
public class ProjectController {
#RequestMapping(value="/updateProject.do",method = RequestMethod.POST,headers ="Accept=multipart/form-data", consumes={"multipart/form-data"}, produces={"text/plain;charset=UTF-8"})
public #ResponseBody String updateProjectDetails(HttpServletRequest request, HttpServletResponse response, #RequestBody ProjectForm command)
{
contractProjectsService.saveProject(command);
return "success";
}
}
here is the header information from chrome headers/request and response data
**General:**
Request URL:http://localhost:9090/SpringMVCAngularJS/updateProject.do
Request Method:POST
Status Code:415 Unsupported Media Type
Remote Address:[::1]:9090
***Response Headers:***
view source
Content-Language:en
Content-Length:1048
Content-Type:text/html;charset=utf-8
Date:Wed, 03 Aug 2016 15:06:05 GMT
Server:Apache-Coyote/1.1
***Request Headers:***
view source
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Authorization:Basic YmVlcDpib29w
Connection:keep-alive
Content-Length:1011
Content-Type:multipart/form-data; boundary=---- WebKitFormBoundaryagdf0LOX4AuXY6SI
Cookie:JSESSIONID=96052E348C6E52F53A594A179E65DE6D
Host:localhost:9090
Origin:http://localhost:9090
Referer:http://localhost:9090/SpringMVCAngularJS/index.html
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
Please help me with the solution.
try to send the comment or other data in request header and send file to contoller ,in controller use" #Requestpart" for accepting file. Use below code for reference..
#Produces("text/plain;charset=UTF-8")
#RequestMapping(value = "/fileUpload/", method = RequestMethod.POST)
public #ResponseBody ResponseCodeModel fileUpload(#RequestPart MultipartFile file,
#RequestHeader(value = "comment") String comment,
)

HTTP headers are not being sent in CORS GET from AngularJS application

My problem is that HTTP headers are not being sent from my AngularJS HTTP GET requests. However, for a HTTP POST, I do see the headers being set. These HTTP requests are over CORS.
Although there are a lot of SO posts on this problem, I have tried them and none of them worked. One of the solutions suggests that HTTP headers are not sent if the data field is empty, and I've tried the suggestion to add an empty data value (which doesn't really sense for a HTTP GET request, by the way), but still, the HTTP headers do not make it.
On a side note, I might defend that this post/question may merit itself as "not a duplicate" (from the other SO posts) as it deals with HTTP GET (as opposed to HTTP POST) and CORS (as opposed to not-CORS).
Here is my technology stack.
NodeJS v4.2.2
Express v4.13.3
AngularJS v1.4.0
To enable CORS, I followed the example here http://enable-cors.org/server_expressjs.html. My NodeJS server application looks like the following.
var express = require('express');
var bodyParser = require('body-parser');
var morgan = require('morgan');
var jwt = require('jsonwebtoken');
var port = process.env.PORT || 8080;
var router = express.Router();
var app = express();
app.set('secret', 'mySecret');
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(morgan('dev'));
app.use('/api', router);
router.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, x-access-token');
res.header('Access-Control-Allow-Methods', 'POST, PUT, GET, OPTIONS, DELETE');
next();
});
router.post('/authenticate', function(req, res) {
var username = req.body.username;
var pw = req.body.password;
if(username !== 'root') {
res.json({
success: false,
message: 'User not found'
});
} else if(pw !== 'root') {
res.json({
success: false,
message: 'Password wrong'
});
} else {
var user = {
username: username,
pw: pw
};
var token = jwt.sign(user, app.get('secret'), {
expiresIn: 60 * 60 * 24 * 365
});
res.json({
success: true,
message: 'Enjoy your token!',
token: token
});
}
});
router.use(function(req, res, next) {
/* according to comments, have to ignore OPTIONS request from protection */
if('OPTIONS' === req.method) { next(); return; } //original post modified here to show, after adding this line, the OPTIONS is accessible, then the GET does actually send the required HTTP header
if('/api/authenticate' === req.originalUrl) {
next();
return;
}
var token = req.body.token || req.params['token'] || req.headers['x-access-token'];
if(token) {
jwt.verify(token, app.get('secret'), function(err, decoded) {
if(err) {
return res.json({
success: false,
message: 'Failed to authenticate token'
});
} else {
req.decoded = decoded;
next();
}
})
} else {
return res.status(403).send({
success: false,
message: 'No token provided'
});
}
});
router.get('/users', function(req, res) {
res.json([
{ fname: 'john', lname: 'doe' },
{ fname: 'jane', lname: 'smith' }
]);
})
var server = app.listen(port, function() {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
My AngularJS service looks like the following.
myServices.factory('HomeService', ['$resource', '$http', '$location', '$cookies', 'conf', function($resource, $http, $location, $cookies, conf) {
var svc = {};
svc.getRestUrl = function() {
return 'http://localhost:8080';
};
svc.sendData = function(url, data, method) {
var restUrl = svc.getRestUrl() + url;
var options = {
method: method,
url: restUrl,
withCredentials: false
};
var token = $cookies.get('token');
if(_.isEmpty(token)) {
options.headers = {
'X-Requested-With': 'XMLHttpRequest'
};
} else {
options.headers = {
'X-Requested-With': 'XMLHttpRequest',
'x-access-token': token
};
}
if(data) {
options.data = data;
} else {
options.data = '';
}
return $http(options);
}
svc.getData = function(url) {
return svc.sendData(url, null, 'GET');
};
svc.postData = function(url, data) {
return svc.sendData(url, data, 'POST');
};
svc.authenticate = function(username, password) {
var data = JSON.stringify({
username: username,
password: password
});
return svc.postData('/api/authenticate', data);
};
svc.getUsers = function() {
return svc.getData('/api/users');
};
return svc;
}]);
Note
for the service's authenticate method, this is a HTTP POST
for the service's getUsers, this a HTTP GET
when there is no data to send (HTTP GET), the data is set to empty data: ''
Using Fiddler, for authenticate I see the following HTTP request.
POST http://localhost:8080/api/authenticate HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 37
Accept: application/json, text/plain, */*
Origin: http://localhost
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36
Content-Type: application/json;charset=UTF-8
Referer: http://localhost/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
{"username":"root","password":"root"}
For getUsers, I see the following HTTP request.
OPTIONS http://localhost:8080/api/users HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://localhost
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36
Access-Control-Request-Headers: accept, x-access-token, x-requested-with
Accept: */*
Referer: http://localhost/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Am I missing something here with regards to HTTP GET over CORS that the HTTP headers are not being sent?
According to your HTTP request, an OPTIONS request is fired to your CORS API icase of your getUsers method.
When it comes to CORS, there are 2 kinds of requests
Simple Requests
Preflighted Requests
Simple requests
A simple cross-site request is one that meets all the following conditions:
The only allowed methods are:
GET
HEAD
POST
Apart from the headers set automatically by the user agent, the only headers which are allowed to be manually set are:
Accept
Accept-Language
Content-Language
Content-Type
The only allowed values for the Content-Type header are:
application/x-www-form-urlencoded
multipart/form-data
text/plain
Preflighted requests
In case you make any request which violates the conditions of a simple request, then a "preflighted" OPTIONS request is sent in order to determine whether the actual request is safe to send.In particular, a request is preflighted if:
It uses methods other than GET, HEAD or POST. Also, if POST is used
to send request data with a Content-Type other than
application/x-www-form-urlencoded, multipart/form-data, or
text/plain, e.g. if the POST request sends an XML payload to the
server using application/xml or text/xml, then the request is
preflighted.
It sets custom headers in the request (e.g. the request uses a header
such as X-PINGOTHER)
For more details about Preflighted Requests, you can refer to this MDN link.
I believe this is what is happening in your case. Even though you're making a simple GET request, you're adding 2 custom headers X-Requested-With & x-access-token which makes it necessary to validate the safety of your API, so a preflighted OPTIONS request is sent by the browser. The browser will continue with your GET request only if it receives valid response.
In your NodeJS server code, you're handling only POST requests to /authenticate and GET requests to /users, so in case of an OPTIONS request, it's going to the default handler where you're checking for token and if it's not available, you respond with a 403. So I suggest you change your code to handle OPTIONS request as well.

spring RESTcontroller to accept dataURI

I am running into a issue of using angularjs ng-img-crop and Spring-boot REST web service.I want to upload an image file from ng crop to my backend web service.
I tried writing a spring controller but it failed and I couldnt find a good tutorial for this. help me resolve this basic request.
Thanks !!!
app.js
angular.module('myApp', [
'ngRoute',
'myApp.view1',
'myApp.view2',
'myApp.version',
'ngImgCrop'
])
.controller('Ctrl',['$scope','notify', function($scope,notify) {
$scope.myImage='';
$scope.myCroppedImage='';
var handleFileSelect=function(evt) {
var file=evt.currentTarget.files[0];
var reader = new FileReader();
reader.onload = function (evt) {
$scope.$apply(function($scope){
$scope.myImage=evt.target.result;
});
};
reader.readAsDataURL(file);
};
angular.element(document.querySelector('#fileInput')).on('change',handleFileSelect);
$scope.submit=function() {
notify($scope.myCroppedImage);
};
}]).
factory('notify',['$http', function($http) {
return function(myCroppedImage) {
var name = 'vishnu';
$http.post('http://localhost:8080/imageUpload', myCroppedImage)
.success(function(data, status, headers, config) {
alert("success");
})
.error(function(data, status, headers, config) {
alert("fail");
});
}
}])
controller.java
#RequestMapping(value="/imageUpload",method=RequestMethod.POST)
#ResponseBody
public String imageUpload(#RequestBody MultipartFile data){
return "success";
}
when I run with the following request, I got some exception in the web service.
Remote Address:127.0.0.1:8080
Request URL:http://localhost:8080/imageUpload
Request Method:POST
Status Code:500 Internal Server Error
Request Headersview source
Accept:application/json, text/plain, /
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:1850
Content-Type:application/json;charset=UTF-8
Host:localhost:8080
Origin:file://
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36**
Request payload
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAFIklEQVR4Xu3VsRHAMAzEsHj/pTOBXbB9pFchyLycz0eAwFXgsCF.......
Response header
Connection:close
Content-Type:application/json;charset=UTF-8
Date:Fri, 24 Apr 2015 12:40:35 GMT
Server:Apache-Coyote/1.1
Transfer-Encoding:chunked
Exception in java
org.springframework.web.multipart.MultipartException: The current request is not a multipart request
First of all your controller should looks like:
public ResponseEntity<Response> fileUpload(#RequestParam("file") MultipartFile file) {
Use #RequestParam instead of #RequestBody, and send the file in a parameter with the same name you're using in the annotation.
Moreover, your request should be sent with type multipart/form-data. For example, a common html for would be:
<form method="POST" enctype="multipart/form-data" action="your url">

AngularJS Satellizer jwt CORS issue when authenticated

i'v got weird behaviour of my code. I'm using Satellizer to authenticate user and when user is not authenticated when i execute this code:
$http.get('http://eune.api.pvp.net/api/lol/eune/v1.4/summoner/by-name/somename?api_key=XXXXXXXXXXXXXXXXX')
.success(function (data) {
console.log(data);
});
my request is ok and i get data
headers:
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4
Connection:keep-alive
Host:eune.api.pvp.net
Origin:http://localhost:9000
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36
but when i authenticate user and try to do same request i get:
XMLHttpRequest cannot load http://eune.api.pvp.net/api/lol/eune/v1.4/summoner/by-name/somename?api_key=XXXXXXXXXXXX. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access. The response had HTTP status code 401.
and headers of this request looks like:
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers:accept, authorization
Access-Control-Request-Method:GET
Connection:keep-alive
Host:eune.api.pvp.net
Origin:http://localhost:9000
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36
my app.config
.config(function ($urlRouterProvider, $stateProvider, $httpProvider, $authProvider, API_URL) {
$urlRouterProvider.otherwise('/');
... some routes ...
$authProvider.loginUrl = API_URL + 'login';
$authProvider.signupUrl = API_URL + 'register';
$authProvider.google({
clientId: 'secret',
url: API_URL + 'auth/google'
});
$authProvider.facebook({
clientId: 'secret',
url: API_URL + 'auth/facebook'
});
// $httpProvider.interceptors.push('authInterceptor');
})
So how should i fix it? I suppose that those headers with Access-Control are the reason, but how should i handle it?
You could try putting the following in the satellizer config:
$authProvider.httpInterceptor = false;
Adding skipAuthorization property in config block might be helpful:
$http.get('http://eune.api.pvp.net/api/lol/eune/v1.4/summoner/by-name/somename?api_key=XXXXXXXXXXXXXXXXX', {
skipAuthorization: true
})
.success(function (data) {
console.log(data);
});
I usually work with the config block by preference. This is how it would look.
//configuration block method:
$http({
method: 'GET',
url: 'http://eune.api.pvp.net/api/lol/eune/v1.4/summoner/by-name/somename?api_key=XXXXXXXXXXXXXXXXX',
skipAuthorization: true
});
Good Luck.
Ok i figured it out. As i supposed Satellizer registers new interceptor, which adds some headers and that's why it doesn`t work. This is satellizer code :
.config(['$httpProvider', 'satellizer.config', function($httpProvider, config) {
$httpProvider.interceptors.push(['$q', function($q) {
var tokenName = config.tokenPrefix ? config.tokenPrefix + '_' + config.tokenName : config.tokenName;
return {
request: function(httpConfig) {
var token = localStorage.getItem(tokenName);
if (token && config.httpInterceptor) {
token = config.authHeader === 'Authorization' ? 'Bearer ' + token : token;
httpConfig.headers[config.authHeader] = token;
}
return httpConfig;
},
responseError: function(response) {
return $q.reject(response);
}
};
}]);
}]);
i handled it by changing one lane to this:
if (token && config.httpInterceptor && httpConfig.rawReq !== true) {
and i pass in my httpConfig option rawReq: true
but this is not nice. Is there posibility to disable specific interceptor ?

How to enable cors request with angular.js-resource

I have an angular.js application and i need to do CORS request.
I want to define my rest services "the angular" using angular resources, described here: http://docs.angularjs.org/tutorial/step_11.
But i haven't found a way to get this working.
On google i found the following sample code: http://jsfiddle.net/ricardohbin/E3YEt/, but this seems not to work with angular-resources.
this is my app.js
'use strict';
angular.module('corsClientAngularApp', ['helloServices'])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.otherwise({
redirectTo: '/'
});
});
this is my services.js with the rest services
angular.module('helloServices', ['ngResource']).
factory('Hello', function($resource){
return $resource('http://localhost:8080/cors-server/hello/:name', {}, {
query: {method:'GET', params:{name:'name'}, isArray:false}
});
});
This is my main.js with the controller using the $http, this works!:
'use strict';
angular.module('corsClientAngularApp')
.controller('MainCtrl', function ($scope, $http, Hello) {
$http.defaults.useXDomain = true;
$http.get('http://localhost:8080/cors-server/hello/stijn')
.success(function(data) {
$scope.hello = data;
});
});
This is another version of my main.js using angular resources. This does NOT work :(
'use strict';
angular.module('corsClientAngularApp')
.controller('MainCtrl', function ($scope, $http, Hello) {
$http.defaults.useXDomain = true;
$scope.hello = Hello.query({name:'stijn'});
});
This is are the headers from the working request (from chrome devtools):
Request URL:http://localhost:8080/cors-server/hello/stijn
Request Method:OPTIONS
Status Code:200 OK
Request Headers
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers:accept, origin, x-requested-with
Access-Control-Request-Method:GET
Cache-Control:max-age=0
Connection:keep-alive
Host:localhost:8080
Origin:http://localhost:9000
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31
Response Headers
Access-Control-Allow-Headers:accept, origin, x-requested-with
Access-Control-Allow-Methods:GET
Access-Control-Allow-Origin:*
Content-Length:0
Date:Thu, 25 Apr 2013 10:42:34 GMT
Server:Apache-Coyote/1.1
And these are the headers from the NOt working request:
Request URL:http://localhost/cors-server/hello/stijn
Request Method:OPTIONS
Status Code:200 OK
Request Headers
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers:accept, origin, x-requested-with
Access-Control-Request-Method:GET
Cache-Control:max-age=0
Connection:keep-alive
Host:localhost
Origin:http://localhost:9000
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31
Response Headers
Allow:GET,HEAD,POST,OPTIONS,TRACE
Connection:Keep-Alive
Content-Length:0
Content-Type:text/plain
Date:Thu, 25 Apr 2013 10:41:12 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.2.22 (Win32)
It looks like the request url is wrong when using angular-resources. But why?
Thanks!
URL for $resource accepts using colon for parameters. Therefore when using port in url you need to escape the colon for port. This is explained in $resource docs

Resources