i have some rest service deployed in my local machine(running on localhost). I am accessing those service using my angular js app. But when i deploy this in firefox i am getting cross origin request block exception but i am able to deploy same angular app on other browser IE and Chrome. Please help me out on this issue.
ErrorMessage:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/helloworld/rest/sayhi. This can be fixed by moving the resource to the same domain or enabling CORS.
$http( { url: 'http://localhost:8080/helloworld/rest/sayhi/'+$scope.userquery, method: 'GET', dataType: 'json',
transformResponse: function(data){
console.log("transformlog "+data);
return JSON.parse(data);
},
headers: {
'Content-Type': 'application/json'
} }).then(function(data){console.log(data);} );
Where the spring mvc services are hosted in tomcat server. Both the server are browsers are in some machine.
http://patrickgrimard.com/2013/12/12/cross-origin-resource-sharing-cors-requests-with-spring-mvc/
I followed above link. I have added Cors headers in my spring-mvc-rest controller using filters and it worked perfect for me.
I think, actually it is problem on server side. You should enable CORS support on your spring application. It can be done by adding the filter
public class CORSFilter extends OncePerRequestFilter {
private final Logger LOG = LoggerFactory.getLogger(CORSFilter.class);
#Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws ServletException, IOException {
LOG.info("Adding CORS Headers ........................");
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
res.setHeader("Access-Control-Max-Age", "3600");
res.setHeader("Access-Control-Allow-Headers", "X-PINGOTHER,Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization");
res.addHeader("Access-Control-Expose-Headers", "xsrf-token");
if ("OPTIONS".equals(req.getMethod())) {
res.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
}
I found it from the link angularjs spring cross-origin request blocked
Related
I have A spring boot application where I allowed all request for CORS filter.
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
And from angular JS I called some rest api of this server app. BUt I am getting following error
Failed to load http://localhost:10230/place: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access. The response had HTTP status code 400.
My angular call like this
function savePlace(place) {
return $http({
method: 'POST',
headers:{'X-TenantID': 'freight_management'},
data: place,
url: 'http://localhost:10230/place'
}).then(function (response) {
console.log(response.data);
return response.data;
}, function (reason) {
return reason;
});
}
How can I solve this?? Anything missing???
You need to configure the allowed origins:
registry.addMapping("/**").allowedOrigins("http://localhost:63342");
Though I solve it by using a proxy today, I used to face this problem like this.
This allows every origin.
This is stored within CorsFilter.java.
#Component
public class CorsFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.addHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, content-type, X-XSRF-TOKEN");
response.addHeader("Access-Control-Expose-Headers", "xsrf-token, x-xsrf-token");
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
filterChain.doFilter(request, response);
}
}
}
Having an issue when I am posting AngularJS data to Web API end point. From the client browser I receive:
405 (Method Not Allowed)
Response for preflight has invalid HTTP status code 405
I have two separate projects which both run in localhost. On my Web Api I have set EnableCors() on config.
If I set content-type of the header to:
'Content-type': 'application/x-www-form-urlencoded; charset=utf-8'
Then it's able to hit my Web API endpoint. However my object argument is null. Could this be XML format rather than JSON? How do I go about resolving this?
Client side code:
function signUp(data) {
$http({
method: 'POST',
url: 'http://localhost:15218/api/account/register',
data: JSON.stringify(data),
headers: {
'Content-type': 'application/json'
}
}).then(function successCallback(response) {
console.log(response);
}, function errorCallback(response) {
console.log(response);
});
}
}
Server Side Method signature:
[HttpPost]
[Route("Register")]
public async Task<HttpResponseMessage> Register(UserCommand command)
You can enable cors on the service by adding global.asax file
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}
Response for preflight has invalid HTTP status code 405
Before making the POST request you want to make, the browser is making an OPTIONS request asking for permission.
The server is responding to the OPTIONS request without a 200 response. The error message tells you that explicitly. (Maybe Access-Control-Allow-Origin cause the problem)
So before anything else, you must check for type of request method. If it is OPTIONS , pass 200 response code.
I am using Restangular with Spring's oauth security and in the client side i am using Restangular for login request.
Code in OAuth2ServerConfiguration:
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("clientapp")
.authorizedGrantTypes("password", "refresh_token")
.authorities("USER")
.scopes("read", "write")
.secret("abc");
}
Login with postman needs these configurations:
1-Set Authorization as "Basic Auth".
2-Set username,password as {"username":"clientapp","password":"abc"}//credentials to access server side
3-In request body through "x-www-form-urlencoded" three parameters are sent.
{"username":"abc#gmail.com","password":"abc123","grant_type":"password"}//credentials to login which are checked from database.
This will do a successful login.but i cannot understand how to use these configurations in Angular JS Restangular call.
currently m trying with this.
In Config:
RestangularProvider.withConfig(function (RestangularConfigurer) {
return RestangularConfigurer.setDefaultHeaders({ "Authorization": "Basic Y2xpZW50YXBwOkxNUw==",
"username":"clientapp",
"password":"abc",
"Content-type": "application/x-www-form-urlencoded; charset=utf-8"
});
In Controller:
Restangualar.all("oauth/login").post({username;$scope.user.username,
password:"$scope.user.password","grant_type":"password"}).then(function(){
console.log(res);
});
But I am getting this error:
error:"unauthorized",error_description:"Full authentication is required to access this resource"
in browser.
Note:This resource is not secured.
Any Solution???
Update: I forgot to added a main information that my frontend with angular is running independently on localhost(through xampp) while spring login backend is on localhost:8080..
Error in network tab:
2-
public void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.authorizeRequests()
.anyRequest().permitAll()
//.antMatchers("/users").permitAll()
.antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll()
.and().csrf().disable();
}
3-
endpoints
.tokenStore(this.tokenStore)
.authenticationManager(this.authenticationManager)
.userDetailsService(userDetailsService)
.addInterceptor(new HandlerInterceptorAdapter() {
public boolean preHandle(HttpServletRequest hsr, HttpServletResponse rs, Object o,FilterChain chain) throws Exception {
rs.setHeader("Access-Control-Allow-Origin", "*");
rs.setHeader("Access-Control-Allow-Methods", "GET,OPTIONS,POST");
// rs.setHeader("Access-Control-Max-Age", "7200");
rs.setHeader("Access-Control-Allow-Headers", "Origin, X- Requested-With, Content-Type, Accept, Authorization");
HttpServletRequest httpServletRequest = (HttpServletRequest) hsr;
if (httpServletRequest.getMethod().equalsIgnoreCase("OPTIONS")) {
chain.doFilter(hsr, rs);
} else {
// In case of HTTP OPTIONS method, just return the response
return true;
}
return false;
}
});
You can use Restangular custom post. See documentation.
Example:
Restangular.service("/oauth/login").one().customPOST(
{},
'',
{
// Params...
grant_type: 'password',
client_id: 'clientapp',
client_secret: 'abc',
username: 'abc#gmail.com',
password: 'abc123',
scope: 'read, write'
},
{
// headers...
}).then(
function (response) {
// Manage successfull response
},
function () {
// Manage error response
}
);
Hope it helps
UPDATED:
It seems to be a CORS problem, lots of answers already for it, but in your case using XAMPP you will need to configure your apache server:
https://enable-cors.org/server_apache.html.
PREVIOUS ANSWER BEFORE UPDATE:
The advantage of using restangular is the ability to manage resources in a more semantic way and the ability to get nested resources. All these advantages don't really apply for a call just to retrieve a token from an oauth2 provider.
I would recommend to forget about using restangular for this specific call (you still can use it for everything else in your application) and convert this call to a simple $http.post.
$http.post('oauth/login',
{ username;$scope.user.username,
password:"$scope.user.password",
"grant_type":"password"
},
{
headers: { "Authorization": "Basic Y2xpZW50YXBwOkxNUw==",
"username":"clientapp",
"password":"abc",
"Content-type": "application/x-www-form-urlencoded; charset=utf-8"
}
})
.then(function(response) {
Restangular.setDefaultHeaders({
"Authorization": "Bearer " + response.token
});
});
So, you just use $http.post, and on its response set the default headers in angular to use the retrieved token.
Cheers,
$http GET request to a clojure backend, to get a list of services.
I get is an OPTIONS request (???), which gets a 405 response...
<code>
var config = {headers: {
'Authorization': 'Bearer d2VudHdvYW5nZV9tZQ',
"X-Testing" : "testing"
}
};
$http.get(SERVER.MESSAGE_SERVICES, config)
.success(function(successCallback) {
$scope.services = successCallback;
})
.error(function(errorCallback) {
console.log(errorCallback.toString);
}).
finally(function() {
console.log("Message services rest call");
});
</code>
**clojure backend**:
<code>
headers {"Access-Control-Allow-Origin" "*"
"Access-Control-Allow-Headers" "X-Requested-With, Origin,Content-Type, Accept"
"Access-Control-Allow-Methods" "GET, POST, OPTIONS"}
</code>
There is no problem that AngularJS sends an OPTIONS request, that is because CORS standards force to do so. Be sure that the server is configured to allow a GET method.
Yes as raso suggested this problem is because of Cross Origin Resource Sharing(CORS). The same old privacy policy prevents JS/ angularJS from making requests across domain boundaries.
Configure server to allow cross domain requests.
Or
If you are using Chrome than you can use this extension to surpass this problem.
I have jersey framework implemented for Rest services version 2.5
I have implemented Get, it works fine and response shows as JSON object in url when I have tried.
When I have tried the same url in angular JS using http.post and $ resource, success comes as 200k but there is no response.
web app deployed in local on glassfish server and jersey rest services deployed in websphere 7
Rest controller
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("/{id}")
public Response assignAppointment(#PathParam("id") String id) {
Appointment app = new Appointment();
app.setId(id);
app.setTechName("fffff");
// return Response.status(200).entity(app).build();
return Response.ok(app).build();
}
in Angular JS
$http.get('http://mylocal.com/ntschedulerp/rest/appointment/'+$scope.appt.apptId,
{
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}}).then(function(appoinmentData)
{
$scope.assignmentForm = "Controller";
$scope.techName=appointmentData.data.techName;
$scope.response1=appointmentData.status;
});
response is empty but status code is 200. but when tried direct url it shows json object i browser. but while accessing from web app, the response is empty..checked in firebug
The issue got resolved. The issue occurred because of the response headers does not accept cross requests.
CORS http request.
Since I have rest server and web app in different servers, angular js does not directly accept the response which does not have specific headers.
To resolve this issue, Both server and client should have headers embedded.
I have resolved as follows
we need add these headers to the response
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods': ['OPTIONS', 'GET', 'POST'],
'Access-Control-Allow-Headers' : 'Content-Type'
On client side, add the magic statement
$http.defaults.useXDomain = true;
before calling $http method in controller, I am using angular js 1.2 version, earlier versions, it might need to do like this..not tested but found some where
app.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}]);
on server side, I am using jersey framework (2.5),
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("/{id}")
public Response assignAppointment(#PathParam("id") String id) {
Appointment app = new Appointment();
app.setId(id);
app.setTechName("xxxx");
ResponseBuilder response=Response.status(200).entity(app);
response.header("Access-Control-Allow-Origin", "*");
response.header("Access-Control-Allow-Methods", "Cache-Control, Pragma,
Origin, Authorization, Content-Type, X-Requested-With");
response.header("Access-Control-Allow-Headers", "GET, PUT, OPTIONS,
X-XSRF-TOKEN");
return response.build();
}
one can use,
#Context HttpServletResponse
as method argument in rest methods, if using older versions.