We have an intranet application we are working on with an AngularJS front end and a Web Api back end. It's basically a redesign of an existing ASP.NET/WCF app and it's only used by a few of our employees.
We had intended to enforce some security in this version (the old one had none) using Windows Authentication and we've had some problems getting that to work with browsers other than Internet Explorer. Chrome, for example always comes back with a 401-Unauthorized error.
I've been instructed to skip the security features for now (yeah I know, not a good idea) so I've disabled them but now I'm seeing an error when I attempt to talk to the API (in a separate project), but in Chrome and not in IE.
XMLHttpRequest cannot load http://localhost:62415/api/Emails. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:50900' is therefore not allowed access. The response had HTTP status code 401.
We've enabled CORS in our API project so I am not sure what I need to do here. We are using localhost in our local development but in QA and production these sites will be using URLs with different subdomains within the same domain.
I am using a Startup class in my project and it has this method:
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseCors(CorsOptions.AllowAll);
app.UseWebApi(config);
}
I must be missing something. We originally had this code in our WebApiConfig but restoring it didn't fix anything:
var cors = new EnableCorsAttribute("*", "*", "*");
cors.SupportsCredentials = true;
config.EnableCors(cors);
Any help is appreciated.
Don't need to add:
var cors = new EnableCorsAttribute("", "", "*");
config.EnableCors(cors);
For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts.
For example, XMLHttpRequest follows the same-origin policy. So, a web application using XMLHttpRequest could only make HTTP requests to its own domain.
However, You can pass that by:
install Microsoft.Owin.Cors package in nuget
add this method in Startup.cs
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
}
Related
I was able to render Text contents from Magnolia public REST API on Salesforce community.
ISSUE: Image files are being blocked by CSP (Content Security Policy)
TRIED: Added the Base URL a few different ways to in Site URL in CSP Trusted Sites
https://*.magnolia-cms.com
https://*.demopublic.magnolia-cms.com
https://demopublic.magnolia-cms.com
Also, included https://demopublic.magnolia-cms.com url in Trusted Sites for Script
What I am missing here?
That looks like a typical case of forgetting setting the CORS headers on Magnolia site, hence browser blocking the request as required by the spec:
For security reasons, browsers restrict cross-origin HTTP requests initiated from scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy. This means that a web application using those APIs can only request resources from the same origin the application was loaded from unless the response from other origins includes the right CORS headers.
More details here
If you haven't done so before, you can add simple static CORS definition in headers using AddHeadersFilter. It was discussed previously eg here
This question already has an answer here:
CORS Unauthorized 401 error when calling spring rest api
(1 answer)
Closed 3 years ago.
I'm trying to send http requests from my React client app to a RestfulApi (built with Spring), but I'm facing CORS issues.
As I understand it to solve cors issue there are several ways, 2 of them that I know:
1) Install a CORS extension on your browser (your browser will be exposed to security risks, but if it's only during development and it can be enabled/disabled then I can live with it)
2) Allow headers from your server rest API- I found a spring annotation called #CrossOrigin(origins = "", allowedHeaders = "")
https://howtodoinjava.com/spring5/webmvc/spring-mvc-cors-configuration/
Using the first approach:
First call that I perform is GET login request and it works, but I'm getting back an empty response with empty headers!
Second call is another GET request to get some projects details, but I'm getting 401!
From some investigation I understood that there is a need to send the browser sessionId (stored in cookies) and pass it to the HTTP request as param in order to be authorized... but didn't manage yet making it works.
I reached this page:
https://www.baeldung.com/spring-security-cors-preflight
Adding another class to my rest server app didn't help as well:
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
// ...
http.cors();
}
}
Install a CORS extension on your browser (your browser will be exposed to security risks, but if it's only during development and it can be enabled/disabled then I can live with it)
CORS extensions tend to just inject Access-Control-Allow-* headers into responses.
They don't do everything else that needs to be done to enable CORS.
In particular, they tend not to handle the preflight requests that need before credentials can be sent in a request. So:
the browser sends a preflight request asking for permission to make a request with credentials
the server responds with an Unauthorized error because the credentials weren't sent
the extension injects Access-Control-Allow-* headers
the browser denied access to the response to the JS because the response had an Unauthorised status (the Access-Control-Allow-* headers not being sufficient to override that)
Implement a real solution when you need CORS. Browser extensions are a waste of time because the will need replacing with real solutions in the end and only work in a subset of cases in the first place.
My system uses AngularJS 1.6 and Spring Boot2.0. My front end is just a simple form that customers can use to buy tickets for an event. When the page loads it will GET the details of the current active event, then the users can fill the form to be POSTed. No login/registration so it's just like a google form. I've built them as separate projects so they will be running in different ports. Now I want to enable csrf protection but I can't seem to make it work.
I tried to follow this tutorial but without the authentication part: https://spring.io/blog/2015/01/12/the-login-page-angular-js-and-spring-security-part-ii. When I did this I encountered a "CORS header ‘Access-Control-Allow-Origin’ missing" on the GET event details part so I added a CORS filter:
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type");
chain.doFilter(request, response);
After adding that, my GET works but I encounter the same CORS error when I POST the customer's details. I can already see the XSRF-TOKEN in the cookie when I use postman but somehow my backend blocks the incoming POST. From my understanding, angular automatically uses a received XSRF token so I didn't modify anything in the frontend when implementing spring security.
I've also tried this one: https://sdqali.in/blog/2016/07/20/csrf-protection-with-spring-security-and-angular-js/. And the exact same result, if I just follow the tutorial, CORS error on GET then when I add simple CORS filter, CORS error on POST. My filters seems to get mixed up on run time.
I've tried playing around the codes in these tutorials along with some answers to related questions here in stack but all of them don't have to deal with the CORS problem.
To begin, you should check my comment on how to enable CORS with spring-boot and spring-security.
As for CSRF protection, spring-boot 2 with spring-security enable that directly. Yet, to use it with AngularJS, you need to follow this guide:
https://docs.spring.io/spring-security/site/docs/current/reference/html5/#csrf-cookie
We are also working on a project with a frontend AngularJS 1.6 and a backend spring-boot 2, but, as we didn't deploy our frontend and our backend on the same url, we got into a problem.
Example:
https://project.company.com/frontend
https://project.company.com/backend
The cookie generated by the server was set on the domain https://project.company.com with context /backend, which was unreadable from our frontend application in AngularJS.
To fix that, we forced our server to send a cookie with a context / so that it could be read from both applications.
#Configuration
#EnableWebSecurity
public class LdapAuthenticationSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
final CookieCsrfTokenRepository csrfTokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
csrfTokenRepository.setCookiePath("/"); // Make sure that the cookie can be read from the backend and the frontend on the same domain.
http.csrf().csrfTokenRepository(csrfTokenRepository);
http.cors();
}
}
In the case where your applications are deployed on different domains, but with the same base like this:
https://frontend.company.com
https://backend.company.com
I would suggest to force the cookie send by the server with a domain like .company.com. But to do so, you will need to modify the way spring-security manage the cookie creation.
I am building a Portal using angularjs and ATG Rest API, It is giving an Error When I am trying to get Session confirmation Number using API:rest/model/atg/rest/SessionConfirmationActor/getSessionConfirmationNumber
Error:XMLHttpRequest cannot load http://IPNUMBER:Port/rest/model/atg/rest/SessionConfirmationActor/getSessionConfirmationNumber. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
API is working fine in POSTMAN, and from the direct browser query.
Please help me on this.
You best bet is to write a simple Pipeline servlet and add it to the RestPipeline configuration. The servlet would just inject the cors headers to all Rest requests.
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import atg.servlet.*;
import atg.servlet.pipeline.*;
public class CORSHeaderServlet extends InsertableServletImpl{
public CORSHeaderServlet () {}
public void service (DynamoHttpServletRequest request,
DynamoHttpServletResponse response)
throws IOException, ServletException
{
//add headers to response.
response.addHeader("Access-Control-Allow-Origin" ,"*");
passRequest (request, response);
}
}
I didn't use this API, but problem is quite common. Have a look for example here (or any other source about CORS):
How does Access-Control-Allow-Origin header work?
If your web application and service have different domains (origins), this will not work until the service allows your application to request data. When you use Postman it works, because Postman does not send the header or uses origin, which is allowed. I don't really know how it works, but it does and it's normal.
If you are using locally hosted application just for testing purposes and both service and app will have the same origin, you have two easy solutions:
You can run web browser (e.g. Chrome) with web security disabled:
Disable same origin policy in Chrome. This disables CORS and eliminates the problem.
You can install Chrome extension called Allow-Control-Allow-Origin: *. When it's enabled, it sends origin which will be allowed by the service.
However, if your service will have different origin, then you will have to configure it to allow your application to request it.
Edit
Note one thing. If you send a request different than GET or with some custom headers, browsers will firstly send an OPTIONS request. It's called preflight request. You're service will have to handle it in order to work properly.
I'm using restangular to consume an api hosted on the same server as the angular files. All requests to the api are getting Origin is not allowed by Access-Control-Allow-Origin errors. I've tried altering headers in the config
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
and updating angular/restangular. Is there a way to set the headers for same domain requests using restangulars setdefaultheaders method?
The error that your are getting is due to Cross Origin Resource Sharing (CORS) policies of your web server.
The resources being on the same server is not enough. They have to be served by the same host.
Is important to understand that api.mydomain.com is a different from www.mydomain.com.
Also having a different port (api.mydomain.com vs api.mydomain.com:9000) makes it a different host.
Check that the response of the response of your server contains the HTTP header:
"Access-Control-Allow-Origin: api.yourdomain.com"
To check how to enable a CORS on your web server check this useful website: enable_cors.org
You can read more about CORS