SAML Authentication - Base URL in sonar.auth.saml.loginUrl ignored?

Template for a good bug report, formatted with Markdown:

sonar.oe.intranet is our internal SonarServer. It seams that it is used like a mask like https://{MYHOST}/adfs/ls/idpinitiatedsignon.aspx - In our case, the SAML IdP and SAML SonarQube are not on the same server

Well as there still is no follow up to my question, I was trying to figure out, which piece of code is responsible for setting up the redirect address to the IdP. But as I am not a Java developer, it is very tricky to find out the the URL is being constructed in order to find out by myself what could be wrong.

So I looked here for example:

or also here:

But there is nothing that could lead to a changed host address other than the configured one.

Hi,

Changed where?

 
Ann

My url is stored correctly in the settings, but when clicking on https://sonar.oe.intranet/sessions/new?return_to=%2Fprojects

<a class=“identity-provider-link” href="/sessions/init/saml?return_to=%2Fprojects" style=“background-color: rgb(68, 68, 68);”><img alt=“SAML Login” height=“20” src="/images/saml.png" width=“20”><span>Log in with SAML>/span<</a>

The http response header “location” is set to:
https://sonar.oe.intranet/adfs/ls/idpinitiatedsignon.aspx?SAMLRequest=SAMLREQUEST_REMOVED_FOR_READABILITY

but it should be
https://myidp.com/adfs/ls/idpinitiatedsignon.aspx?SAMLRequest=SAMLREQUEST_REMOVED_FOR_READABILITY

Hi,

So you have https://myidp.com/adfs/ls/idpinitiatedsignon.aspx configured in SonarQube as your “SAML login url” but you end up at https://sonar.oe.intranet/adfs/ls/idpinitiatedsignon.aspx?

 
Ann

Yes, exactly. https://myidp.com/adfs/ls/idpinitiatedsignon.aspx turns into https://sonar.oe.intranet/adfs/ls/idpinitiatedsignon.aspx

Hi,

Is it possible you’re being redirected there by a proxy?

 
Ann

Hi again,

Or perhaps your identity provider is redirecting inappropriately?

Could you follow the SAML traffic via developer tools and see if you’re being sent to the wrong URL by SonarQube or by your provider?

E.G.

 
Ann

Hi Ann,

When clicking the link https://sonar.oe.intranet/sessions/init/saml?return_to=%2Fprojects I can see the server response in Google Chrome and the “location” HTTP Header already contains the wrong URL.
There is no proxy involved, the IdP is not even called, because of the wrong URL.

I could not figure out, where is a wrong configured URL, as in the SAML settings I can see the correct link.

If you want to see it yourself, we can also do a MS Teams call?

Thanks,
Dominik

PS: I try to figure out, where the link is created in the SonarQube source code, but I am not a Java developer so I don’t know where to start :frowning:

Any ideas what could be the reason or where to start?
I am still open for an MS Teams call if you want @ganncamp ?

Hi,

SonarQube doesn’t natively support HTTPS, so if you’re serving it at an HTTPS URL, there must be a proxy involved. So you should probably talk to your network folks. Additionally, turning the SonarQube server logging up to TRACE level may give you some useful data (altho you won’t want to leave it at TRACE for long; the logs get big fast at that level).

 

It is hosted by IIS that serves the SSL on the same server, so there is at least no network involved.
So the wrong address is generated through SonarQube.

In the logs you’ll see it as well:
“GET /sessions/init/saml?return_to=%2Fprojects%3Fsort%3D-size HTTP/1.1” 302 - “https://sonar.oe.intranet/sessions/new?return_to=%2Fprojects%3Fsort%3D-size” “Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36” “AYAdruc7X0L7h+fwAAAO”

“GET /adfs/ls/idpinitiatedsignon.aspx?SAMLRequest=SAMLREQUEST&RelayState=3tsf7tj8kildgpqtbbhd4f6nnn HTTP/1.1” 200 - “https://sonar.oe.intranet/sessions/new?return_to=%2Fprojects%3Fsort%3D-size” “Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36” “AYAdruc7X0L7h+fwAAAP”

“GET /api/users/current HTTP/1.1” 200 91 “https://sonar.oe.intranet/adfs/ls/idpinitiatedsignon.aspx?SAMLRequest=SAMLRequest&RelayState=3tsf7tj8kildgpqtbbhd4f6nnn” “Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36” “AYAdruc7X0L7h+fwAAAS”

Hi,

Can you turn on the trace logging and see what shows up in web.log?

 
Thx,
Ann

I don’t find anything special there:
web.log (85.9 KB)

Do you know where in the code the URL for the redirect is constructed? Maybe it would help to look to finde out if there is a bug when constructing this URL?

Hi,

The stuff relevant to SAML doesn’t show up until you enable TRACE level logging. You’ll only want to do it briefly because at TRACE level, the logs get big fast. But turn that on, recreate the problem, and post the relevant log snippet (not the entire log, please!).

 
Ann

Hi,

The only option where I’ve set from INFO to TRACE was in
conf\wrapper.conf, like here:

wrapper.console.format=PM
wrapper.console.loglevel=TRACE
wrapper.logfile.format=M
wrapper.logfile.loglevel=TRACE
wrapper.logfile.rollmode=DATE
wrapper.logfile=…/…/logs/sonar.YYYYMMDD.log

(I always stopped and started the Windows service of SonarQube, after changing the values above)

Is there somewhere else a config where to change the level?

thx,
Dominik

Hi Dominik,

Check Administration → System at the top-right of the page:

Selection_122

 
Ann

Hi,

Thanks for the advice, here is what seems to be relevant:

06:24:23 TRACE web[o.s.s.p.w.UserSessionFilter] Thread[http-nio-0.0.0.0-9000-exec-4,5,main] serves /sessions/init/saml
06:24:23 TRACE web[sql] time=0ms | sql=select p.prop_key as "key", p.is_empty as empty, p.text_value as textValue, p.clob_value as clobValue, p.component_uuid as componentUuid, p.user_uuid as userUuid from properties p where p.prop_key=? and p.component_uuid is null and p.user_uuid is null | params=sonar.plugins.risk.consent
06:24:23 TRACE web[sql] time=0ms | sql=select p.prop_key as "key", p.is_empty as empty, p.text_value as textValue, p.clob_value as clobValue, p.component_uuid as componentUuid, p.user_uuid as userUuid from properties p where p.prop_key=? and p.component_uuid is null and p.user_uuid is null | params=sonar.forceRedirectOnDefaultAdminCredentials
06:24:23 TRACE web[sql] time=0ms | sql=select p.prop_key as "key", p.is_empty as empty, p.text_value as textValue, p.clob_value as clobValue, p.component_uuid as componentUuid, p.user_uuid as userUuid from properties p where p.prop_key=? and p.component_uuid is null and p.user_uuid is null | params=sonar.auth.saml.enabled
06:24:23 TRACE web[sql] time=0ms | sql=select p.prop_key as "key", p.is_empty as empty, p.text_value as textValue, p.clob_value as clobValue, p.component_uuid as componentUuid, p.user_uuid as userUuid from properties p where p.prop_key=? and p.component_uuid is null and p.user_uuid is null | params=sonar.auth.saml.providerId
06:24:23 TRACE web[sql] time=0ms | sql=select p.prop_key as "key", p.is_empty as empty, p.text_value as textValue, p.clob_value as clobValue, p.component_uuid as componentUuid, p.user_uuid as userUuid from properties p where p.prop_key=? and p.component_uuid is null and p.user_uuid is null | params=sonar.auth.saml.applicationId
06:24:23 TRACE web[sql] time=15ms | sql=select p.prop_key as "key", p.is_empty as empty, p.text_value as textValue, p.clob_value as clobValue, p.component_uuid as componentUuid, p.user_uuid as userUuid from properties p where p.prop_key=? and p.component_uuid is null and p.user_uuid is null | params=sonar.auth.saml.loginUrl
06:24:23 TRACE web[sql] time=0ms | sql=select p.prop_key as "key", p.is_empty as empty, p.text_value as textValue, p.clob_value as clobValue, p.component_uuid as componentUuid, p.user_uuid as userUuid from properties p where p.prop_key=? and p.component_uuid is null and p.user_uuid is null | params=sonar.auth.saml.certificate.secured
06:24:23 TRACE web[sql] time=0ms | sql=select p.prop_key as "key", p.is_empty as empty, p.text_value as textValue, p.clob_value as clobValue, p.component_uuid as componentUuid, p.user_uuid as userUuid from properties p where p.prop_key=? and p.component_uuid is null and p.user_uuid is null | params=sonar.auth.saml.user.login
06:24:23 TRACE web[sql] time=0ms | sql=select p.prop_key as "key", p.is_empty as empty, p.text_value as textValue, p.clob_value as clobValue, p.component_uuid as componentUuid, p.user_uuid as userUuid from properties p where p.prop_key=? and p.component_uuid is null and p.user_uuid is null | params=sonar.auth.saml.user.name
06:24:23 TRACE web[sql] time=0ms | sql=select p.prop_key as "key", p.is_empty as empty, p.text_value as textValue, p.clob_value as clobValue, p.component_uuid as componentUuid, p.user_uuid as userUuid from properties p where p.prop_key=? and p.component_uuid is null and p.user_uuid is null | params=sonar.core.serverBaseURL
06:24:23 DEBUG web[c.o.saml2.Auth] Settings validated
06:24:23 DEBUG web[c.o.s.a.AuthnRequest] AuthNRequest --> <samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="ONELOGIN_f24c5134-eecd-4764-8d3e-344a2a04a8d4" Version="2.0" IssueInstant="2022-04-20T04:24:23Z" Destination=" https://myidp.com/adfs/ls/idpinitiatedsignon.aspx" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="https://sonar.oe.intranet/oauth2/callback/saml"><saml:Issuer>https://sonar.oe.intranet/</saml:Issuer><samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" AllowCreate="true" /></samlp:AuthnRequest>
06:24:23 DEBUG web[c.o.saml2.Auth] AuthNRequest sent to  https://myidp.com/adfs/ls/idpinitiatedsignon.aspx --> fZLBbtswDIZfxdDdluOoayEkAbJm3QJkSdBkO+wysBLTCpEpV5Sb7u2nOhvWHVpAgACKP/l/pCYMre/0vE8PdIuPPXIqnltPrIeHqegj6QDsWBO0yDoZvZt/XemmqnUXQwomePFK8r4CmDEmF0gUy8VUbNafVpvPy/XPQ6PMxWisSkRjS3X5QZVXdozlWClooFZwZZUovmPkrJ2KXCoXYO5xSZyAUg7VTVPWqmzqfa10k8/4hygWmccRpEH1kFLHWsrT0XFl8ak6HUMFSYI9sPQsne0cueQgoWV3T4Eq4O5ZFNs/nB8dWUf37yPenZNYf9nvt+V2s9uLYv4X+zoQ9y3GHcYnZ/Db7eqfLQ4EsQqYbREmGSDvpJEGvL8Dc5QvwxWzyculB/Q4e0M5ka+TJucNr7PR5WIbvDO/ipsQW0hvc4yq0RBxtjwMqbon7tC4g0ObcbwPp+uIeVBTkWKPopCzc9f/v9LsNw==
06:24:23 TRACE web[o.s.s.p.w.UserSessionFilter] Thread[http-nio-0.0.0.0-9000-exec-1,5,main] serves /adfs/ls/idpinitiatedsignon.aspx

So I can see in the log files what would be the correct address, but I can see in the HAR-trace of the browser that it is not.
You’ll find the false request directly after that in the log ( 06:24:23 TRACE web[o.s.s.p.w.UserSessionFilter] Thread[http-nio-0.0.0.0-9000-exec-1,5,main] serves /adfs/ls/idpinitiatedsignon.aspx ) that the next call is on itself.

Hi,

So the change was made somewhere between SonarQube and the browser. I think you need to look at your proxy.

 
Ann

Hi,

There is NO proxy in between, the SonarQube instance is only served by IIS where there are no settings, especially it would not make any sense, that only the SAML link is wrong and all other links are fine. Which proxy would modify just one part of the redirect address and keep the rest, in this case i am 98% sure, that is not IIS.

The link is sent wrong to the browser by the application.

Do you know which part of the source code is responsible for the redirect url when navigating to
https://sonar.oe.intranet/sessions/init/saml?return_to=%2Fprojects
so at least I can investigate it myself?

Thank you
Dominik