SSL is required to authenticate keycloak behind traefik - spring

I have the problem that my spring application with the keycloak adapter give me this warning:
SSL is required to authenticate. Remote address IP is secure: false, SSL required for: EXTERNAL .
The keycloak address is with https
Every request to my backend is blocked with a 401 Error and this warning in the console.
Keycloak is behind a reverse proxy: traefik
I also tried to remove the headers with traefik:
- traefik.http.middlewares.sso.headers.customrequestheaders.X-Forwarded-For=
- traefik.http.middlewares.sso.headers.customrequestheaders.X-Forwarded-Proto=
- traefik.http.middlewares.sso.headers.customrequestheaders.X-Forwarded-Host=
- traefik.http.middlewares.sso.headers.customrequestheaders.X-Real-IP=
Edit: I can fix it with keycloak.ssl-required = none and also in the admin panel but is this safe?

keycloak.ssl-required = none is definetly not a secure work around. There is Keycloak doc, which describe how to configure it properly:
https://www.keycloak.org/docs/latest/server_installation/index.html#_setting-up-a-load-balancer-or-proxy

Related

How can you deploy a spring boot application with HTTPs without making any changes to the application?

I have a spring boot application which works over http.I do not want to touch the application - so no keystore etc. I want to use reverse proxy - i.e. the request will land at some other machine over TLS and
will get redirected to my spring boot application over secure socket layer. How it could be done?
Edit: When I try to login to that site, developer tool console tells me:
"Mixed Content: The page at 'https://xxxx-uat.xxxx.com:4200/login' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://151.253.73.106:9091/login'. This request has been blocked; the content must be served over HTTPS."
Nginx reverse proxy is being used.
Best way to do it is to use cloudflare. Cloudflare is free for basic use. You can create a new site, point to your HTTP URL and configure SSL as flexible. So, now your service is behind https. Cloudflare will act as proxy. Request will go to cloudflare via https, then it will be routed to your http.

Spring Boot Redirect HTTP to HTTPS on Same Port

I have a Spring Boot 1.5.21 application which runs on HTTPS. I want to redirect HTTP requests into HTTPS for same port. My application.yaml is as follows:
server:
port: 8443
error:
whitelabel:
enabled: false
ssl:
key-store: classpath:keystore/tomcat.p12
key-store-type: PKCS12
key-store-password: password
key-alias: tomcat
When I enter this into URL bar:
http://localhost:8443
I see that error as usual:
Bad Request
This combination of host and port requires TLS.
When I refresh the page, doesn't happen. When I click the URL bar and click enter again at Chrome, link is redirected.
My questions:
How can I make that URL:
http://localhost:8443
automatically redirect to:
https://localhost:8443
If below is not applicable, how can I remove that message?
There is a similar question here which asks for different ports and answer does not work for my case:
Spring Boot redirect HTTP to HTTPS

Mixed Content error because of Keycloak default login redirection

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).

Browser not responding to www-authenticate challenge for bookmarked ssl (https url) to restricted resource

I have set up SSO using weblogic on windows and Kerberos, It is working fine for the http pages, however I observed a strange behavior on https pages which requires CONFIDENTIAL setting for the transport, It works fine if I first access a page on http which is not configured as secured in web.xml(Transport-Gurantee as None) and then the https page.
But If I try to hit the https url directly which is configured with Transport-Gurantee as CONFIDENTIAL then it shows the Basic Auth Dialog and a 401 Unauthorized response, Looking at the logs I see that the Server responded with the WWW-Authenticate but browser showed the Basic Auth Dialog in response instead of getting the Authorize token.
Does anyone has any idea on what might be issue here, If there is any problem with the browser settings then it would not have worked irrespective of accessing the http url first.
I can see the following error log in weblogic console
Malformed request "Can not parse URI from http request". Request parsing failed, Code: -1
Found one of the link here
SPNEGO on IBM WebSphere Portal 6.1 with https
For my case it is weblogic 12c , I don't think reinstalling 12c is a valid solution for it
Ok I got it fixed , It turns out to be an issue with the browser configuration , the https://myserver.domain.com was not inside the intranet domain and the control to do that rests with the windows Admin team, once they added it , the https urls are also working fine.

How to get SpringSecurity/Grails to play nicely with a Load Balancer that is terminating SSL

We have a Grails app on Tomcat deployed behind a Load Balancer that is terminating SSL (the load balancer then communicates with tomcat instances on port 8080). We have configured SpringSecurity to require a secure channel on all resources, pay attention to the headers from the load balancer, to force https and to map the ports from the load balancer:
grails.plugin.springsecurity.secureChannel.useHeaderCheckChannelSecurity = true
grails.plugin.springsecurity.auth.forceHttps = true
grails.plugin.springsecurity.portMapper.httpPort = 80
grails.plugin.springsecurity.portMapper.httpsPort = 443
grails.plugin.springsecurity.secureChannel.definition = [
'/**': 'REQUIRES_SECURE_CHANNEL'
]
Most of this is working correctly - redirects from within Grails are using the https protocol as expected, as well as most ajax requests.
There are some ajax requests however that are not working correctly. They all relate to results of interacting with j_spring_security* endpoints like j_spring_security_check. For example, if a user tries to login via ajax, we get this error in the browser (this is the redirect that the successful login initiates):
Mixed Content: The page at 'https://www.servernamehere.com/' was loaded over HTTPS, but
requested an insecure XMLHttpRequest endpoint 'http://www.servernamehere.com/login/ajaxSuccess'.
This request has been blocked; the content must be served over HTTPS.
The same problem happens upon unsuccessful authentication:
Mixed Content: The page at 'https://www.servernamehere.com/' was loaded over HTTPS, but requested
an insecure XMLHttpRequest endpoint 'http://www.servernamehere.com/login/authfail?ajax=true'.
This request has been blocked; the content must be served over https.
How can we configure spring security to understand that all redirects coming out of authentication events need to be https?
We were able to fix this issue by creating a custom Redirect strategy (implement org.springframework.security.web.RedirectStrategy) and replacing the default redirect strategy bean with our custom one. The custom redirect strategy examines the headers passed in by the load balancer and makes sure that the response is redirected to the appropriate protocol
I have a similar setup where I set in my Grails app secureChanel headers like this:
grails.plugin.springsecurity.secureChannel.useHeaderCheckChannelSecurity = true
grails.plugin.springsecurity.portMapper.httpPort = 80
grails.plugin.springsecurity.portMapper.httpsPort = 443
grails.plugin.springsecurity.secureChannel.secureHeaderName = 'X-Forwarded-Proto'
grails.plugin.springsecurity.secureChannel.secureHeaderValue = 'http'
grails.plugin.springsecurity.secureChannel.insecureHeaderName = 'X-Forwarded-Proto'
grails.plugin.springsecurity.secureChannel.insecureHeaderValue = 'https'
There was a bug in both versions (2.x, 3.x) of Grails spring security plugin https://github.com/grails-plugins/grails-spring-security-core/issues/395 however it has been fixed already....

Resources