4
First I’ll tell you what happens!
I developed a simple Spring Boot project to show on screen a GRID having as Frond-End the Angular, the request of the java API is the port 8080 and Angular is port 4200, as each one makes different requests I decided to use the CORS, but I had no positive result and gave this error message;
Failed to load resource: the server responded with a status of 401 ()
localhost/:1 Failed to load http://localhost:8080/lancamentos?resumo: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'http://localhost:8000' that is not equal to the supplied origin. Origin 'http://localhost:4200' is therefore not allowed access.
core.js:1350 ERROR Error: Uncaught (in promise): Response with status: 0 for URL: null
at resolvePromise (zone.js:824)
at resolvePromise (zone.js:795)
at eval (zone.js:873)
at ZoneDelegate.invokeTask (zone.js:425)
at Object.onInvokeTask (core.js:4621)
at ZoneDelegate.invokeTask (zone.js:424)
at Zone.runTask (zone.js:192)
at drainMicroTaskQueue (zone.js:602)
at ZoneTask.invokeTask [as invoke] (zone.js:503)
at invokeTask (zone.js:1540)
Then Recapitulating!
My system is making a request on port 8000 from the Frond-End 4200 localhost. When a request is made by a protocol a domain on ports other than the origin, which is my case, the Angular application is at port 4200 the Java API is at port 8080 in which case for security browsers restrict access, does not allow the request to be made, the browser itself already has this layer of security that restrict access.
but there is a mechanism known as CORS that allows the service providers to configure the access control cross Domain, ie with the protocol, with domain or ports different from the origin, the back-end I’m using already has the implementation of cross Domain.
To give permission to my packaged project, I executed this command:
java -jar algamoney-api-1.0.0-SNAPSHOT.jar --
spring.datasource.username=root
--spring.datasource.password=1234
algamoney.origin-permitida=http://localhost:4200
But it didn’t work. He denied me permission as you can see.
So I made another attempt, look at my CORS settings in my Spring Boot project:
package com.example.algamoney.api.config.property;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("algamoney")
public class AlgamoneyApiProperty {
private String originPermitida = "http://localhost:8000";
private final Seguranca seguranca = new Seguranca();
public Seguranca getSeguranca() {
return seguranca;
}
public String getOriginPermitida() {
return originPermitida;
}
public void setOriginPermitida(String originPermitida) {
this.originPermitida = originPermitida;
}
public static class Seguranca {
private boolean enableHttps;
public boolean isEnableHttps() {
return enableHttps;
}
public void setEnableHttps(boolean enableHttps) {
this.enableHttps = enableHttps;
}
}
}
And estancio for this other java class that does everything:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
@Autowired
private AlgamoneyApiProperty algamoneyApiProperty;
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
response.setHeader("Access-Control-Allow-Origin", algamoneyApiProperty.getOriginPermitida());
response.setHeader("Access-Control-Allow-Credentials", "true");
if ("OPTIONS".equals(request.getMethod()) && algamoneyApiProperty.getOriginPermitida().equals(request.getHeader("Origin"))) {
response.setHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, PUT, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept");
response.setHeader("Access-Control-Max-Age", "3600");
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, resp);
}
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
You may have noticed that class Algamoneyapiproperty is with port 8000 and my Frond-End Angular is configuring for port 8080, which is why I executed command requesting permission through the MSDOS, then no longer depend on requests from MSDOS I decided to change the request port of my Java API to 8080 and my Frond-End to 8080.
Only by default, my API will run on the 8080 localhost running on the 8080 request and my Angular Frond-End will run on the 4200 localhost requesting the 8080 request from the java API as you can see below
API Java
Class Algamoneyapiproperty
Private string originPermitida = "http://localhost:8080";
Frond-End Angular
import { Http, Headers } from '@angular/http';
import { Injectable } from '@angular/core';
import 'rxjs/add/operator/toPromise';
@Injectable()
export class LancamentoService {
lancamentosUrl = 'http://localhost:8080/lancamentos';
constructor(private http: Http) { }
pesquisar(): Promise<any> {
const headers = new Headers();
headers.append('Authorization', 'Basic YWRtaW5AYWxnYW1vbmV5LmNvbTphZG1pbg==');
return this.http.get(`${this.lancamentosUrl}?resumo`, { headers })
.toPromise()
.then(response => response.json().content)
}
}
The result was the same, and generated the same error as was commented at the beginning of this post.
My next attempt was to try with other doors, I tried with 9000, 7654 and with 8000.
Someone might claim that maybe door 8080 might be in trouble! So I set up my CORS in my Java API to accept any source, as you can see below;
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
// @Autowired
// private AlgamoneyApiProperty algamoneyApiProperty;
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
if ("OPTIONS".equals(request.getMethod())) {
response.setHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, PUT, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept");
response.setHeader("Access-Control-Max-Age", "3600");
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, resp);
}
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
And just took!
So the problem is not at the door, the problem may be in the CORS configuration.
Anyone may ask! Why don’t you keep using the API to accept any source?
I don’t want to do this because I can lower the security level.
I really need to know where my CORS configuration error is to accept a specific source.
thanks for your attempt to help me, but your answer doesn’t help much, because in the same way that the Java API works in a development environment is to work also in a production environment without any gambit, that is, your approach it is functional, but it is not good programming practice. Please do not be offended by what I have said, if you happen to know someone from your contacts who can see my post and can help me, I know very grateful.
– wladyband
Dude, using proxy is not a gambiarra. It is a resource used for development and also used for production. If you want a better help start by writing your question better and be more objective.
– Giovane
I’m sorry but my question is well elaborated, if you have questions would look more elegant to ask questions about what you didn’t understand from my post, I don’t know if in fact proxy approach can be made in production environment.
– wladyband
If it can be done I invite you to test on any model found on github, again it was not my intention to be awkward with you, but of the projects I found using CORS most do not use good development practices and why I made this post. And of the projects I found on Github I couldn’t find any similar approach to what you did to be applied in a production environment. That’s why I’ve been so sure to tell you who’s not a good practice.
– wladyband
But if you still do not accept and were offended even if it was not my intention I invite you to withdraw your answer because for me it will not serve.
– wladyband
If your application architecture is done using Docker containers, communication between these containers is done via proxy. If you have a scalable micro-service architecture where you have no idea how many services are standing to serve you or which address of them, you hit the loadbalancers which in addition to managing the requests for the services intelligently, it acts as a proxy.
– Giovane
Again I’m sorry the way I wrote, I try at most to be very receptive in my comments because here are a lot of nervous people in the stackoverflow forum and who is in need of help is me. I’m gonna do it the way it’s on your blog.
– wladyband
I made the changes, but it didn’t work gave the same error message, could you take a look at the Frond-End code to see if I did something wrong? please https://github.com/wladyband/erro1/tree/master/wladimi-ui
– wladyband