Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Spring Oauth2 Authentication AWS behind Zuul #942

Closed
Writtscher opened this issue Apr 1, 2016 · 11 comments
Closed

[Question] Spring Oauth2 Authentication AWS behind Zuul #942

Writtscher opened this issue Apr 1, 2016 · 11 comments

Comments

@Writtscher
Copy link

Hi,

I have a question / problem. I've checked everything I could but didn't find a solution. I hope you can help me. My problem is similiar to this issue, I have the same setup:


https://url.net/service
  |-> AWS load balancer
      - adds X-Forwarded-* 
      - converts" https to http
      |-> http://localhost:10000/service
          - Finds correct service for given path
          |-> Service get hit and I see the correct header in the log but the service 
              does not redirect me to  the "X-Forwarded-Host" but to https://localhost/login

Zuul log:

Request url: /uaa
Request header: x-forwarded-for XXX.XXX.XXX.XXX (AWS standard)
Request header: x-forwarded-port 443
Request header: x-forwarded-proto https

Service log:

Request url: /uaa
Request header: x-forwarded-host XXX.XXX.XXX.XXX (same as  the zuul x-forwarded-for header. I configured server.tomcat.remote-ip-header: X-Forwarded-Host)
Request header: x-forwarded-port 443
Request header: x-forwarded-proto: https
Request header: x-forwarded-prefix: /uaa

Everything looks ok for me. But it does not work as I would expect.. My problem is that the default LoginUrlAuthenticationEntryPoint does not care about the headers and redirects unauthenticated users to http://localhost/login. This issue might fix it in the future but does not help me right now 😓. The debug log says it o.s.s.web.DefaultRedirectStrategy: Redirecting to 'https://localhost/login'. Also there is another log entry that shows that the header are not supported o.s.s.w.s.HttpSessionRequestCache: DefaultSavedRequest added to session: DefaultSavedRequest[https://localhost/server]

I have

server.use-forward-headers: true

activated for zuul and the service - but it does not help at all.

Another strange thing is that the zuul server redirects the user correctly. Not to http:localhost/login but the X-Forwarded-For server with /login path.

I have no ideas anymore. Could you please point me in the right direction?

Edit:
If I do curl http://localhost:10100/service/login on the sercver I see that the location response header is the correct location path,, but spring security does not redirect me to the provided host.. Im totally confused. Somewhere down the line the X-Forwarded-{For/Host} header gets lost?

Edit 2:
If I config

server.tomcat.remote-ip-header: X-Forwarded-Host

I don't see the request header logged anymore instead the header X-Forwarded-For XXX.XXX.XXX is logged.. If I configure

server.tomcat.remote-ip-header: X-Forwarded-For

I don't see the request header logged anymore instead the header X-Forwarded-Host is logged... Wtf?

@Writtscher
Copy link
Author

Another strange thing is: My zuul server is also a web server, it contains also a view (root url) that is secured. If I visit https://xxx/ then zuul correclty redirects me to https://xxx/login. It just does not work for the services behind zuul. If I call https://xxx/service/login then the application correctly authenticates the user but does redirect the user back to https://localhost/service..

I've no idea anymore. I've tested everything.. Hope anyone understands my problem 😕

@ddewaele
Copy link

@Writtscher : Did you manage to find a solution for this ? having the exact same issue....

@ddewaele
Copy link

@Writtscher : I just switched my auth server to Jetty instead of Tomcat and now the redirect is working properly.

@Writtscher
Copy link
Author

Yep. I'll post it tomorrow. It's simple even tough I'm not sure whether it's the perfect solution.

I've added a zuul filter (last in the chain) that puts the 'X-Forwarded-For' header of my AWS Loadbalancer into the host. Without this 'work around' zuul always passes 'localhost' as host header.

This is kinda bad for my services..

@Writtscher
Copy link
Author

Switching to jetty fixed it? Not sure if you have the same issue. My 'auth server' (salesforce) works correctly. It's just the service behind zuul that redirects the user to 'localhost/context/login' instead of 'mydomain/context/login'. As I said: I have fixed it with a zuul filter that modifies the 'host' header and passes the modified header down to my service.

@ddewaele
Copy link

when accessing resources behind my zuul proxy the redirection to the login page (from the oauth2 login server) went to localhost/uaa/login while it should have gone to mydomain/uaa/login

Switching to Jetty fixed it.

Think your setup is pretty similar

@Writtscher
Copy link
Author

Yep same archi.. I'll post my solution tomorrow. But you don't have to wait, as I said I've added a simple zuul filter (spring component) that runs with order 10000. This filter sets the loadbalancer domain/ip as host header and passes it down. Then spring security should redirect you correctly. Very simple.

@Writtscher
Copy link
Author

@Order(2)
@Component
@SuppressWarnings("unchecked")
public class CorrectHeadersFilter extends ZuulFilter {

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 10000;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext currentContext = RequestContext.getCurrentContext();

        currentContext.addZuulRequestHeader("host",  currentContext.getRequest()
                .getHeader("host"));

        // XXX
        currentContext.getZuulRequestHeaders().remove("x-forwarded-prefix");

        ((Set<String>) currentContext.get("ignoredHeaders")).clear();// XXX
        return null;
    }

}

Three things happening here:

  • I just put the 'host' header back into the 'host' header (could also use 'X-Forwarded-For' since the AWS Loadbalancer provides it out of the box, but the 'host' header is the same and I don't want to rely on any AWS headers). If I remove this line then zuul puts 'localhost' into the 'host' header and this yields into redirects to 'localhost/context/login' instead of 'mydomain/context/login'.
  • My backend services are configured to use 'X-Fowarded-xx' headers and zuul provides them. My backend services have a context (server.context-path). This means if I don't remove the "X-Forwarded-Prefix" spring oauth2 redirects me to my auth server with a wrong redirect uri. It's always "mydomain/context/context/login". Removing this header fixes it. Removing the context path is not an option. Removing the 'use forwarded headers' configuration does not work as spring oauth2 constructs a wrong redirect uri.
  • Zuul configures ignored / sensitive headers (Cookie, Set-Cookie, Authorization). These headers are removed from the request / response. Since all of our services have a frontend and rely on a session we need cookies (JSESSIONID).

This fixes our problems for now. We are not 100% sure that these "fixes" are ok but it is ok for now.

@damienpolegato
Copy link

damienpolegato commented Apr 28, 2016

I have a similar issue where /login sends me to system host (http://stackoverflow.com/questions/36881835/spring-mvc-web-app-behind-zuul-redirect-issue). Will try your fix, thanks.

@kakawait
Copy link
Contributor

@Writtscher I had the same issue but I have a custom EntryPoint that is building request using X-Forwarded-* headers. But solution you provide above can be a better way! I will try that

@spencergibb
Copy link
Member

Closing this due to inactivity. Please re-open if there's more to discuss.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants