We are using Keycloak 2.0.0.Final installed behind a nginx proxy on a RedHat environment.
We are currently facing a problem with the Reset Password functionality which send an email with the internal server host instead of the external one in the action URL as we are behind a proxy.
I receive this by email: https://internal/auth/realms/MYREALM/login-actions/reset-credentials?code=wYhHP(...) but the end user should see https://external/auth/realms/MYREALM/login-actions/reset-credentials?code=wYhHP(...). The whole proxy settings work perfectly otherwise, it's basically an URL rewriting function.
I found this ticket relating a similar case but the solution isn't ideal: http://lists.jboss.org/pipermail/keycloak-user/2015-October/003428.html
Any hidden properties, settings we could use or solution to fix this issue?
Thanks
Nginx sets the emailed URL prefix from the contents of the Host header, so your nginx proxy needs to be configured to pass the Host header intact.
Something like this:
proxy_pass <your internal keycloak URL or IP address>
...
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
...
You may also need to set X-forwarded-proto if your internal URL is not https
Related
I'm trying to use keycloak in my load balance service with Nginx.
But when I call service API, I received the error "Too Many Redirects" in browser.
I guess this process should be:
1. Request load-balanced to service A
2. Keycloak in service A redirect to login page
3. Login with password & username
----------------The above is correct----------------------------------
4. Keycloak redirect to the original page but **load-balance to service B**
5. Keycloak in service B redirect to login page
6. Auto login without password
7. Keycloak redirect to the original page but load-balance to service A
8. Keycloak in service A redirect to login page
9. Auto login without password
10. Then loop forever...
bug
How should I change my keycloak config and fix the bug?
nginx.conf:
http {
upstream backend{
server 127.0.0.1:8001 weight=1;
server 127.0.0.1:8002 weight=1;
}
...
...
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
...
...
}
}
And Springboot keycloak config in the application.properties:
server.port=8002 # modify by command line
keycloak.auth-server-url=http://172.20.51.25:8080/auth
keycloak.realm=autocv
keycloak.public-client=true
keycloak.resource=oauthtest
keycloak.securityConstraints[0].authRoles[0]=aps
keycloak.securityConstraints[0].securityCollections[0].name= common
keycloak.securityConstraints[0].securityCollections[0].patterns[0]=/*
keycloak client config
You should follow the Official Keycloak Guide Setting Up a Load Balancer or Proxy. Also don't forget to add the following configuration as mentioned in the official docs.
proxy-address-forwarding
Also enable reverse proxy configurations for your configurations.
Configure your reverse proxy or loadbalancer to properly set X-Forwarded-For and X-Forwarded-Proto HTTP headers.
Configure your reverse proxy or loadbalancer to preserve the original Host HTTP header.
Configure the authentication server to read the client’s IP address from X-Forwarded-For header. - from Keycloak Documentation - Identifying Client IP Addresses
I have nginx that will handle https, but the login and register forms of keycloak have http actions and I can't find a way to set them to https.
Making them to https in the browser works correctly.
There are two variables:
{url.registrationUrl}
{url.loginAction}
Where are these values coming from?
EDIT:
I made a workaround
{url.registrationUrl?replace('http', 'https')}
Use proxy-address-forwarding.
Forward the original schema in Nginx (server.conf)
proxy_set_header X-Forwarded-Proto $scheme;
Use this information in Keyclok (standalone/domain.xml)
proxy-address-forwarding=true in http-listener
https://www.keycloak.org/docs/latest/server_installation/index.html#identifying-client-ip-addresses
INFORMATION NEEDED:
I use Keycloak (Docker version) behind a Spring project.
(The client side of this project is React and communication between client and backend is provided by REST services.)
The client side is secured and using "https" scheme.
It is my Spring configuration:
keycloak:
auth-server-url: https://sso-ssoha.b9ad.pro-us-east-1.openshiftapps.com/auth
realm: master
resource: clientname
public-client: true
THE ROOT OF THE PROBLEM:
When I click a link from client, it calls a Spring service normally.
But before that, it redirects to default login page of Keycloak with adding this path sso/login to the current "https" url but changing scheme to "http".
But, redirecting from https to http create a problem like this:
Mixed Content: The page at 'https://www.helpful.army/contents/Problem' was loaded over HTTPS, but requested an insecure resource 'http://serviceha-helpfularmy.b9ad.pro-us-east-1.openshiftapps.com/sso/login'. This request has been blocked; the content must be served over HTTPS.
it seems that we need let keycloak web server aware of we are using proxy, https://serverfault.com/questions/1000567/keycloak-blank-page-behind-nginx-reverse-proxy, after set PROXY_ADDRESS_FORWARDING variable, it works.
I have solved this problem and similar ones with these steps:
(1) Frontend side:
You know, www.helpful.army is an educational project which has an interface running on React and it is in NGINX server.
So, I appended the default NGINX server config with mandatory headers:
location / {
try_files $uri /index.html;
proxy_set_header X-Forwarded-Proto $scheme;
**add_header Access-Control-Allow-Origin *;**
}
(2) Backend side:
I have created a different client on Keycloak just for the Spring-Boot backend and set is as a "Bearer-only" one.
keycloak:
auth-server-url: https://sso-ssoha.b9ad.pro-us-east-1.openshiftapps.com/auth
realm: master
resource: serviceha
bearer-only: true
ssl-required: "external"
confidential-port: 0
verify-token-audience: true
I also add this configuration for application.yml:
server:
port: 8443
remote_ip_header: x-forwarded-for
protocol_header: x-forwarded-proto
use-forward-headers: true
(3) I have changed all ports from interface to backend as 8443
I had the same problem when I migrated to Keycloak X. Starting from Keycloak 17, there is no setting for PROXY_ADDRESS_FORWARDING.
For me setting the proxy=passthrough helped.Check https://www.keycloak.org/server/all-config for more details.
In newer version of keycloak you can configure the proxy setting with the value passthrough. In the case of docker, you want to pass the setting via the environement variable KC_PROXY=passthrough (keycloack config docs).
I am using spring mvc for my web application, but redirect acts a little weird.
I have a code adding a user to the database for signup and redirecting a user to another page, but when I deploy it into my server, the redirect keeps looking for 'localhost' instead of the domain name.
here is my code. It's pretty simple.
public ModelAndView register(HttpServletRequest request, HttpServletResponse response) {
// does a successful database process.
return new ModelAndView("redirect:survey1.do?enabled=true&page=0");
}
But when it reaches that line, somehow it tries to redirect a user to localhost, even though it is not running locally.
Is it related to any spring configuration? I used spring framework before a little bit, but I haven't run into this kind of problem.
Thanks.
Assuming you're using a good old UrlBasedResourceViewResolver which creates RedirectView instances to handle redirect view names, then, no, Spring doesn't do anything that would cause the redirect to go to localhost.
The RedirectView will simply use HttpServletResponse#sendRedirect(String) to send the redirect. The javadoc for that says
If the location is relative without a leading '/' the container
interprets it as relative to the current request URI
So, with a URI of
http://your-uri-host.com/web-app-context/whatever
a redirect view name like
redirect:survey1.do?enabled=true&page=0
will cause Spring to send a 302 response with a Location header of
Location: http://you-uri-host.com/web-app-context/survey1.do?enabled=true&page=0
There must be something else in your setup (or you user's browser) that is causing this.
I have faced with same issue when spring-boot was behind a proxy. Nginx in my case. You should pass http-header Host from Nnginx to spring-boot. So spring-boot can figure out what is the original URL
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
proxy_connect_timeout 240;
proxy_send_timeout 240;
proxy_read_timeout 240;
proxy_pass http://localhost:9912;
}
Above is my nginx configuration, as I can see i'm passing Host header. Otherwise spring-boot thinks that I'm running at localhost:9912
I can say that Cloudflare pass this header correctly, not sure about AWS load balance.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I'm using nginx for proxy cache and I'm having trouble to make it cache some ajax requests.
Nginx are making cache correctly for all pages but not for ajax requests.
The uri for ajax requests are like: /process/leaveyourmessage/getMessages?id=XX
My location config is:
location / {
proxy_pass http://mydomain.com:8080;
proxy_cache microcache;
proxy_cache_valid 200 5s;
proxy_cache_use_stale updating;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
On the http block I've added:
proxy_cache_path /var/cache/nginx levels=1:2
keys_zone=microcache:5m max_size=1000m;
Anyone know what could be the problem?
My back end is apache + php
I've found the problem. Nginx respect cache-control and expires header and those ajax was sending it.
Writing down "proxy_ignore_headers Cache-Control Expires;" made it work.