getsentry / self-hosted

Sentry, feature-complete and packaged up for low-volume deployments and proofs-of-concept
https://develop.sentry.dev/self-hosted/
Other
7.91k stars 1.78k forks source link

Keycloak SAML - There is no AttributeStatement on the Response #3062

Closed sgohl closed 5 months ago

sgohl commented 6 months ago

Self-Hosted Version

24.6.0.dev0

CPU Architecture

x86_64

Docker Version

24.0.5

Docker Compose Version

2.16.0

Steps to Reproduce

Precondition:

I followed the instructions from here: https://yyhh.org/blog/2020/10/how-to-setup-saml2-authentication-on-sentry-with-keycloak/

With the difference that keycloak metadata url now is without the auth before realms in uri.

I tried also with Name ID format "username" and "email" – no difference. (because https://github.com/getsentry/self-hosted/issues/2743#issuecomment-1916180615)

I tried ACS/SLS uris both with and without organization name at the end of uri – no difference. (because https://github.com/getsentry/self-hosted/issues/1344#issuecomment-1085827928)

For mappers, I have set them in the default created dedicated scope for the client in tab "Client scopes" (this was reorganized in new keycloak version). (I also tried creating a new scope and add this mapper, and then add the scope (type default) to the client – no difference) I deleted the roles_list mapping and only added predefined "x500 email" with SAML Attribute Name changed to user_email

Other steps:

Keycloak and Sentry running via docker on same host, but communication via https over central SSL terminated reverse proxy (HAProxy) using real LetsEncrypt cert.

Both IdP User ID and User Email: user_email Both First Name and Last Name empty for now (elimination testing).

Click "Save Attributes" -> redirect to Keycloak/https works -> Login as admin -> Redirect back to Sentry/https -> Error: image

I used a SAML tracer browser plugin, and indeed, the AttributeStatement is missing in the saml reposonse: https://gist.github.com/sgohl/9f6504746b43c518be4f54d7889ae6fd

I'm stuck debugging. There are no logs in keycloak (level DEBUG) or sentry-web. It seems, keycloak just omits this statement because it has no reason to include it which is no error per se. So I think, something is missing in keycloak configuration, but I can't figure what.

I've found and read these issues:

and applied any conclusion I found, but for me, nothing worked.

I understand, this is most likely not a sentry issue itself but rather a keycloak configuration, but since the keycloak configuration highly depends on what sentry expects, I feel it belongs to here.

Highly appreciate any help! Perhaps someone could share their anonymized keycloak client configuration and share how a correct saml response with the AttributeStatement looks like!

Expected Result

AttributeStatement on the Response not missing - as expected

Actual Result

Authentication error: SAML SSO fehlgeschlagen, There is no AttributeStatement on the Response

Event ID

No response

azaslavsky commented 5 months ago

Are you seeing any errors in your sentry-web-1 server logs when you try to do this?

This does seem to be some unique keyclock + sentry combination error, hard to speculate what might be causing it though. We have a specific way of doing it on prod that unfortunately doesn't overlap much with the self-hosted flow.

madalinignisca commented 5 months ago

Create in Client Scopes a new entry, name it Sentry for example, or how you wish if you will reuse it.

Create mapper with x500 email, firstname and lastname. Another custom mapper will be for username.

Make sure to make all attributes very simple:

Screenshot 2024-05-21 at 17 27 32

Now make sure the Sentry client will use the Client Scope.

This means that Keycloak will return in the response the attributes expected by Sentry, which you must match on the sentry configuration form.

This happens on recent Sentry with lastest 24.x of Keycloak. I spent like 4-5h trying all combination possible from all github issues and referenced blog posts. None work anymore.

sgohl commented 5 months ago

Hi, thanks for your response!

So you made it working?

I removed the mappers from the dedicated builtin scope and created a new client scope "sentry" (and added to the client as type Default) with mappers for email and username (I didn't know that username needs a mapper, too?), and tried with NameFormat as Basic as well as with default urn. Same with firstName and lastName. None worked.

I tried with naming the email/user attribute email and user_email but both diodn't work (is the name relevant?)

Again tried client/NameFormat as "username" and "email".

@madalinignisca Could you possibly share the relevant parts of your client configuration (via keycloak export from the Action dropdown) via gist for a day or two so I could compare to mine?

@azaslavsky

there's only one none-200 log in sentry-web:

sentry-self-hosted-web-1  | 08:19:27 [INFO] sentry.access.api: api.access (method='GET' view='sentry.api.endpoints.organization_auth_provider_details.OrganizationAuthProviderDetailsEndpoint' response=204 user_id='1' is_app='False' token_type='None' is_frontend_request='True' organization_id='1' auth_id='None' path='/api/0/organizations/sentry/auth-provider/' caller_ip='10.242.2.92' user_agent='Mozilla/5.0 (X11; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0' rate_limited='False' rate_limit_category='None' request_duration_seconds=0.041001319885253906 rate_limit_type='DNE' concurrent_limit='None' concurrent_requests='None' reset_time='None' group='None' limit='None' remaining='None')

but I doubt that it's in any way helpful to understand what the problem is, and I'm not even sure it's the corresponding request to the error

azaslavsky commented 5 months ago

It is very surprising that you are getting errors in the UI, but nothing in the web logs. If you open your chrome devtools when you see that error (from the original post), are there any notable 4xx or 5xx codes?

sgohl commented 5 months ago

no 4xx or 5xx requests in network inspector, no adblocker, no relevant bad logs in browser console, neither firefox nor chrome

as far as I see, there is a first POST request to sentry which responds with 302 to keycloak, which responds with 200. Although this is a Authentication Redirect, it automatically redirects and uses my keycloak-admin login to automatically proceed and redirect back to sentry

Finally a 204 No Content Response from sentry

image

madalinignisca commented 5 months ago

@sgohl export.json

{
  "clientId": "https://[sentry_host_name]/saml/metadata/[sentry_org]/",
  "name": "",
  "description": "",
  "rootUrl": "",
  "adminUrl": "",
  "baseUrl": "",
  "surrogateAuthRequired": false,
  "enabled": true,
  "alwaysDisplayInConsole": false,
  "clientAuthenticatorType": "client-secret",
  "redirectUris": [
    "https://[sentry_host_name]/*"
  ],
  "webOrigins": [],
  "notBefore": 0,
  "bearerOnly": false,
  "consentRequired": false,
  "standardFlowEnabled": true,
  "implicitFlowEnabled": false,
  "directAccessGrantsEnabled": true,
  "serviceAccountsEnabled": false,
  "publicClient": true,
  "frontchannelLogout": false,
  "protocol": "saml",
  "attributes": {
    "saml.assertion.signature": "false",
    "saml.force.post.binding": "true",
    "saml_single_logout_service_url_post": "https://[sentry_host_name]/saml/sls/",
    "saml.encrypt": "false",
    "saml_assertion_consumer_url_post": "https://[sentry_host_name]/saml/acs/",
    "saml.server.signature": "true",
    "saml.server.signature.keyinfo.ext": "false",
    "saml.signing.certificate": "[certificate]",
    "saml.artifact.binding.identifier": "[some-uuid]",
    "saml.artifact.binding": "false",
    "saml.signature.algorithm": "RSA_SHA256",
    "saml_force_name_id_format": "false",
    "saml.client.signature": "false",
    "saml.authnstatement": "true",
    "display.on.consent.screen": "false",
    "saml_name_id_format": "username",
    "saml.signing.private.key": "[key]",
    "saml.allow.ecp.flow": "false",
    "saml_signature_canonicalization_method": "http://www.w3.org/2001/10/xml-exc-c14n#",
    "saml.onetimeuse.condition": "false",
    "saml.server.signature.keyinfo.xmlSigKeyInfoKeyNameTransformer": "NONE"
  },
  "authenticationFlowBindingOverrides": {},
  "fullScopeAllowed": true,
  "nodeReRegistrationTimeout": -1,
  "defaultClientScopes": [
    "Sentry"
  ],
  "optionalClientScopes": [],
  "access": {
    "view": true,
    "configure": true,
    "manage": true
  }
}
madalinignisca commented 5 months ago

@sgohl make sure you have the mappers right and used in the client!

I have this, and in each one, there is the SAML Attribute Name expected by Sentry and matching your configuration.

Screenshot 2024-05-26 at 10 40 15
madalinignisca commented 5 months ago

The problem is not with Sentry. Sentry works fine with custom SAML2 providers.

The problem is lack of information anywhere on the internet how to setup Keycloak for any usecase. There are many tutorials for some popular integrations, but nothing relevant for majority. Probably most companies end with some paid saas solution (AD included), as those are preconfigured for most case scenarios.

Keycloak is a bare bones solution for which who manages is fully responsible to know expectations of CLIENT and setup all required scenarios.

If you are trying Keycloak and you don't have anything else setup in it, maybe a more simple SAML provider alternative would better help, like lemonldap-ng or simplesamlphp, which compared to Keycloak are human level stuff, where Keycloak is enterprise level made to justify time consumed to configure it.

sgohl commented 5 months ago

@madalinignisca

Thank you for your answers, but I still got nowhere after testing everything. Actually, I think keycloak is pretty straight-forward and logical to me. Thanks also for your recommendations, although I'd rather not to, especially when you managed to get it working with keycloak.

I already coupled Keycloak with Windows Active Directory.

I'm not sure if Sentry is able to let users login with their username, aka sAMAccountName, or if it expects / must be an email address, and if it then depends what Name ID Format to choose (username or email). I see in your config, you use username, but do your users login with email? For that reason, I also tried setting the username mapper to the User Property email.

There are also multiple types of mappers – I tried both "User Property" and "User Attribute" and NameFormats (also tried both Basic and urn)

And also, to me there is no sense to create two mappers (username and email) which point to the same actual Property in the UserModel. But I did everything in every constellation.

Sometimes/randomly I get "No Signature found. SAML Response rejected" although I don't know what tiny bit of a change caused that and what it actually means

this is my current client scope configuration.

image image image image image image image image

is there maybe anything that is not particular obvious that I would need to set anywhere that just didn't get focus yet? Is a working user federation a requirement? Although I can browse/search AD users

I'm also almost certain that the built-in client scope should equally work image

sgohl commented 5 months ago

I got it. It had nothing to do with the mappers, they were fine.

My misconception was: I switched between the two error messages:

1) There is no AttributeStatement on the Response 2) No Signature found. SAML Response rejected

while I thought 1) would be a step further. But it wasn't. Inspecting the SAML response showed the AttributeStatements for all mappers. In contrary to this comment https://github.com/getsentry/self-hosted/issues/1571#issuecomment-1187012447 that said, fixing the mappers fixed the issue, for me it was the following problem:

EVERY tutorial out there said: Disable the Signing stuff (Sign documents, Sign assertions)

But actually that is what was missing. Now i have:

image

and it works.