Configuring SAML Authentication with Microsoft Entra ID for SonarQube behind HAProxy

Must-share information (formatted with Markdown):

  • Which versions are you using (SonarQube Server / Community Build, Scanner, Plugin, and any relevant extension)
    SonarQube Server / Community Build: sonarqube:25.7.0.110598-community
  • How is SonarQube deployed: zip, Docker, Helm
    Docker
  • What are you trying to achieve
    SAML authentication with Microsoft Entra ID
  • What have you tried so far to achieve this
    Configured SAML authentication following official documentation

This is related to this post: configuring-saml-authentication-with-microsoft-entra-id-for-sonarqube but now uses HAProxy instead of Nginx. So, it’s necessary to read the previous post first to understand most of the configurations, here I’ll just put the HAProxy configurations. I want to share how I successfully implemented SAML authentication with Microsoft Entra ID behind HAProxy.

There are variables that need to be replaced according to your own configurations:

  • PUBLIC_IP
  • FQDN_SONARQUBE_URL.DOMAIN.COM
  • SonarQube_Docker_IP

This is the HAProxy configuration for reference:

frontend redirectTOHttps
	bind			PUBLIC_IP:80 name PUBLIC_IP:80   
	mode			http
	log			global
	option			dontlognull
	option			http-keep-alive
	option			forwardfor
	acl https ssl_fc
	http-request set-header		X-Forwarded-Proto http if !https
	http-request set-header		X-Forwarded-Proto https if https
	timeout client		30000
	http-request set-var(txn.txnpath) path
	http-request redirect scheme https code 301

frontend SharedFE_HTTPS-merged
	bind			PUBLIC_IP:443 name PUBLIC_IP:443   ssl crt-list /var/etc/haproxy/SharedFE_HTTPS.crt_list  
	mode			http
	log			global
	option			socket-stats
	option			dontlognull
	option			log-separate-errors
	option			httplog
	option			http-keep-alive
	option			forwardfor
	acl https ssl_fc
	http-request set-header		X-Forwarded-Proto http if !https
	http-request set-header		X-Forwarded-Proto https if https
	timeout client		30000
	acl			SonarQube-Host	var(txn.txnhost) -m str -i FQDN_SONARQUBE_URL.DOMAIN.COM
	http-request set-var(txn.txnhost) hdr(host)
	http-request set-header X-Real-IP %[src]  if  SonarQube-Host
	http-request set-header X-Forwarded-For %[src]  if  SonarQube-Host
	http-request set-header X-Forwarded-Proto https  if  SonarQube-Host
	http-request set-header X-Scheme https  if  SonarQube-Host
	http-request set-header X-Forwarded-Protocol https  if  SonarQube-Host
	http-request set-header X-Forwarded-Host %[req.hdr(Host)]  if  SonarQube-Host
	http-request set-header X-Forwarded-Port 443  if  SonarQube-Host
	http-response set-header X-Frame-Options SAMEORIGIN  if  SonarQube-Host
	http-response set-header X-Content-Type-Options nosniff  if  SonarQube-Host
	http-response set-header X-XSS-Protection "1; mode=block"  if  SonarQube-Host
	http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains"  if  SonarQube-Host
	use_backend SonarQube-BE_ipvANY  if  SonarQube-Host


backend SonarQube-BE_ipvANY
	mode			http
	id			117
	log			global
	option			log-health-checks
	http-response replace-header Set-Cookie "^((?:(?!; [Ss]ecure\b).)*)\$" "\1; secure" if { ssl_fc }
	timeout connect		30000
	timeout server		30000
	retries			3
	load-server-state-from-file	global
	http-request set-header X-Forwarded-Proto https 
	http-request set-header X-Forwarded-Protocol https 
	http-request set-header X-Scheme https 
	http-request set-header X-Forwarded-Ssl on 
	http-request set-header X-Forwarded-Port 443 
	http-request set-header X-Forwarded-Host %[req.hdr(host)] 
	http-request set-header X-Forwarded-For %[src] 
	http-response replace-header Set-Cookie "^([^=]+=[^;]*)(.*)" "\1; SameSite=None\2" if { res.hdr(Set-Cookie) -m found } 
	server			SonarQube-Docker SonarQube_Docker_IP:9000 id 118 check inter 1000  resolvers globalresolvers 

Notes

  • Ensure your HAProxy version supports the directives used in this configuration
  • The SameSite=None cookie setting is crucial for SAML authentication to work properly with modern browsers
  • Test the configuration thoroughly in your environment before deploying to production
2 Likes