I tried to send a Javascript XHR request that includes a
'Authorization: Basic base64encodedCredentials'
header through a Zuul proxy. Behind the proxy is my Spring Security Server that exposes an endpoint which is secured by Basic HTTP authentication. My server reacts with a 401 ("unauthorized"). If I send the same request via curl, all is well.
Using a network monitoring tool, I observed that the header Zuul is sending looks like this:
'authorization: Basic base64encodedCredentials' (notice the lowercase 'a' in 'authorization')
After I had a look at the source code of BasicAuthenticationFilter in Spring Security, I suspect that the lowercase 'a' is the reason why my XHR request is not authenticated by my server.
Is this a bug in Zuul ? What do you think ?
Edit: http header names are actually case insensitive.
So Zuul is not to blame. What else has then caused the authentication to fail ?
I was looking at the wrong place.
For everyone stumbling over this, I'll depict what happened:
My Zuul route was set to
http://<host>/<securityContext>/auth/token
while it should have been set to
http://<host>/<securityContext>/oauth/token (notice the extra 'o')
The wicked reaction of the Spring Security Server was not to respond with a '404' ("not found") to the wrong route, but with a '401' ("unauthorized"). This lead me to the assumption that there is something wrong with the authentication header (or some other header for that matter).
As of now, I don't know why the Security Server responded that way. It seems to me that there is actually an endpoint exposed under /auth/token.
Related
What I want to do
Calling an URL which is proxied by the oauth2 proxy. The oauth2 proxy should perform an authorization code flow in case no authentication is available. In case there is already an authentication available, the access token should be set to the Authorization Header in the request which is forwarded to the upstream.
What I tried
According to the documentation I'd expect that, when setting --pass-authorization-header the token which is requested should be added to the authorization header.
I also experimented with --pass-access-token which should set an X-Forwarded-Access-Token header.
I couldn't see this header at my service either.
Could someone explain to me what I'm doing wrong?
I found the solution.
This post on a github issue lead me to my mistake.
I did misunderstand what the request is and what the response is and how to handle them using nginx ingresses.
If you are using OAuth2-Proxy with a Kubernetes ingress using nginx subrequests (https://kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/) the data that comes back to nginx is actually an HTTP response, so you will need to use HTTP Response headers (the --pass-* options configure request headers to the upstream).
Try --set-authorization-header and then you need to use this annotation to have the Kubernetes take the subrequest response header and add it to the proxied request header: nginx.ingress.kubernetes.io/auth-response-headers
https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#external-authentication
I work in project that uses microservice architecture with JWT, every thing is good but when I send the Authorization in the request from client (Angular app) it is checked by the api-gateway (ZuulFilter) and after that the request is sent to auth-server, the problem is that I don't find the Authorization in the header and every data is lost. Any one has an idea ?
The solution was to add he property sensitive-headers in zuul properties and remove "Authorization" from default value as explained here and here
When i send Authorization Header from rest client(postman), also from browser, to back end springboot(2.0.3v) AuthorizationService (without API Gateway), the 'Authorization' Header will be exists and every flow works fine.
But when i send the same Header through API Gateway, The 'Authorization' Header will be missed. This header will be present in all filters of API Gate way. But it will be missed in backend(AuthorizationService)'s filter.
Kindly help what might be cause? any filter is intercepting to avoid Authorization Header? I have also registered CORS Filter with Access-Control-Allow-Origin to "" and Access-Control-Allow-Headers to "".
API gateway has a lambda proxy integrated when you are integrating lambda function with it, if ur wrapping a http url to it, you need to pass the header in Method integration section and also enable CORS by clicking on resource and manually adding the headers with custom name and enabling cors might help.
I have one micro service "user-service". It is secured with spring-cloud-oauth2. It has one REST endpoint "/data/v1" which returns some JSON response.
When I send GET request to this endpoint it gets redirected to /oauth/login for authentication and after successful authentication it returns the token and then I am able to get the JSON response.
Later I added zuul proxy service ("micro-proxy-service") to route all external requests to internal back end services like "user-service".
It has single route "/resource" which then forwards the request to "/data/v1"
But now if I send GET requests to "/resource/data/v1" even after successful oauth2 authentication I get HTTP 302 response code with redirection to /login page.
If I try to access the "/data/v1" without zuul proxy then I am able to get response after oauth2. But when I request through zuul then I get 302.
If I remove the oauth2 from "user-service" then I can access "/data/v1" in both ways: directly or through zuul.
Please let me know If I am missing anything in zuul configuration.
Thanks.
Zuul strips the authentication headers by default, to enable them use the following configuration
zuul:
sensitiveHeaders: Cookie,Set-Cookie
A CORS POST request (AJAX) made by my client server (running on Apache # port 443) to my REST server (running on Tomcat # port 8443), fails to trigger when tried over HTTPS.
Please note that all the requests function properly without SSL.
I have already set the withCredentials: true options in the request fields. And my Tomcat server also takes care of the appropriate headers :
response.addHeader("Access-Control-Allow-Origin", "https://localhost");
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
response.addHeader("Access-Control-Allow-Methods", "OPTIONS, POST");
I also tried using Curl, but the issue persisted over SSL. However, the Tomcat server responds to all my requests when tried directly over Postman/through the browser.
Could someone tell me what I'm missing out here?
I'm assuming this is an issue with the preflight request. There are two types of CORS requests: simple, and not-so-simple.
The simple kind is either a GET or POST with no custom headers whose content type is "text/plain".
The not-so-simple kind is any request using custom headers, utilising request methods other than POST or GET, and using different content body types. These requests will be "preflighted"; that is the browser will make a preflight request on the clients behalf in order to determine whether or not the server will allow this request. The preflight request uses the OPTIONS method. I'm willing to bet if you use something like Firebug to have a look what's going on you'll see something like this in the Net tab: "OPTIONS activity" with a status of "Aborted".
Unfortunately the preflight request doesn't pass the client certificate to the server which is why your request is failing to trigger. You need to disable two way SSL in order to get it working. In Apache you can try changing the SSLVerifyClient to:
SSLVerifyClient optional
I've used this before in order to get my cross domain AJAX calls working over HTTPS.
Good luck.