Spring boot zuul wrong redirection of request

I am developing an API Gateway to redirect a request to some microservice. This is part of the application.properties file:

#     _____                                       _____.__
#    /  _  \ ______ ______     ____  ____   _____/ ____\__| ____
#   /  /_\  \\____ \\____ \  _/ ___\/  _ \ /    \   __\|  |/ ___\
#  /    |    \  |_> >  |_> > \  \__(  <_> )   |  \  |  |  / /_/  >
#  \____|__  /   __/|   __/   \___  >____/|___|  /__|  |__\___  /
#          \/|__|   |__|          \/           \/        /_____/

server.port=8088
server.servlet.context-path=/PetApp

#  __________           .__    _________                _____.__
#  \____    /__ __ __ __|  |   \_   ___ \  ____   _____/ ____\__| ____
#    /     /|  |  \  |  \  |   /    \  \/ /  _ \ /    \   __\|  |/ ___\
#   /     /_|  |  /  |  /  |__ \     \___(  <_> )   |  \  |  |  / /_/  >
#  /_______ \____/|____/|____/  \______  /\____/|___|  /__|  |__\___  /
#          \/                          \/            \/        /_____/

#Routes for Auth
zuul.routes.tokenGenerator.path=/auth/login
zuul.routes.tokenGenerator.url=http://localhost:8086/PetApp_Auth/auth/generateToken
zuul.routes.tokenGenerator.stripPrefix=false

I am trying to redirect the request from the API gateway (http://localhost:8080/PetApp/auth/login) to the service running in (http://localhost:8086/PetApp_Auth/auth/generateToken) I have sent with postman the request directly to the microservice and it works perfectly.

IMPORTANT: I am not adding any authorization header because this endpoint is not securitized (And it works perfectly) but the rest of the API in my auth microservice is securitized

but when I try to send the request through the API gateway I get the following:

As can be seen, the request is being redirected to the right microservice (Auth service) but not to the right URL, because I have an exception for the rest of the endpoints and URL that is being shown.

I have also tried to put the authorization token previously generated and send in the header, but I get the same not authorized

What I am doing wrong?

Upvotes: 1

Views: 1638

Answers (2)

I have already solve it by adding a filter. Zuul build the full URL like service service defined URL + PATH, so I implemented a filter that deletes the path and now the request are perfectly received in the other microservices. Anyway I am planing to change end points definitions to have the same endpoints Path than in the ones defined in the microservices, because with variable paths I thinks it is imposible to solve that. I will also check to use another solutions like nginx or varnish as @Maxim Sagaydachny suggested

@Component
public class PathConfigFilter extends ZuulFilter {

    @Autowired
    private ZuulProperties zuulProperties;

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER + 1;
    }

    @Override
    public boolean shouldFilter() {
        return RequestContext.getCurrentContext().getFilterExecutionSummary().toString()
            .contains( "PreDecorationFilter[SUCCESS]" );
    }

    @Override
    public Object run() {

        RequestContext context = RequestContext.getCurrentContext();

        String originalRequestPath = (String) context.get(FilterConstants.REQUEST_URI_KEY);

        //PathVariable change
        URL routeHost = (URL) context.get( "routeHost");
        String modifiedPathVariable = processPathVariableRoutes( routeHost.getPath(), originalRequestPath );
        if(modifiedPathVariable != null){
            try {
                URL newUrl = new URL(routeHost,modifiedPathVariable);
                context.put("routeHost", newUrl);
            } catch (MalformedURLException e) {
                throw new ApiGatewayException( ApiGatewayErrorCodes.PATH_VARIABLE_ERROR );
            }
        }

        //Delete the path because the full path is defined in properties
        context.put(FilterConstants.REQUEST_URI_KEY, "");

        return null;
    }

    private String processPathVariableRoutes(String routeHost, String requestPath){

        if(!routeHost.contains( "*" )){
            return null;
        }

        ArrayList<String> splitedRoute = new ArrayList<>(Arrays.asList(routeHost.split( "/" )));
        splitedRoute.remove( 0 );
        String context = "/" + splitedRoute.get( 0 );
        String realPath = context + requestPath;

        return realPath;
    }
}

Thank you very much.

Upvotes: 1

Armen Arzumanyan
Armen Arzumanyan

Reputation: 2063

Maybe you need to disable Spring security in zuul or auth microservice. Just remove spring security dependencies, make sure token passed from zuul to auth...

Upvotes: 0

Related Questions