Einführung von SAML bei bestehender Benutzerbasis

Meine aktuelle Discourse-Installation hat die Registrierung neuer Benutzer deaktiviert, und die Anmeldung erfolgt über das LDAP-Plugin (GitHub - jonmbake/discourse-ldap-auth: Discourse plugin to enable LDAP/Active Directory authentication. · GitHub). Viele interne Benutzer existieren daher bereits mit unterschiedlich erstellten Inhalten.

Mir wurde aufgetragen, auf SAML umzustellen, um unseren Okta-Workflow zu integrieren. Ich habe das Plugin (GitHub - discourse/discourse-saml: Support for SAML in Discourse · GitHub) mit der Option DISCOURSE_SAML_AUTO_CREATE_ACCOUNT: true installiert. Die Anforderung lautet: Benutzer anlegen, falls sie noch nicht existieren. Falls der Benutzer bereits existiert (weil er zuvor über LDAP erstellt wurde), muss derselbe Benutzer wiederverwendet werden. Das von mir beobachtete Verhalten ist jedoch, dass versucht wird, einen neuen Benutzer mit einem bereits vorhandenen Benutzernamen anzulegen, was natürlich zu Fehlern führt. Wenn ich die Option zum automatischen Erstellen entferne, erscheint ein Popup, in dem die Registrierungsdaten bearbeitet werden können – der Benutzername ist zwar korrekt voreingestellt, aber mit einer numerischen Präfixierung, um Konflikte zu vermeiden. Das ist in meinem Fall jedoch keine Option.

Haben Sie irgendwelche Vorschläge?

Vielleicht ist dieser alte Beitrag relevant, aber er wurde bisher nicht beantwortet:
https://meta.discourse.org/t/verify-if-user-is-already-logged-sso-with-saml2-discourse-saml/73213
(Ich kann in diesem Beitrag leider nicht mehr als zwei Links einfügen, Entschuldigung.)

Vielen Dank im Voraus.
AB

Die Benutzer werden normalerweise anhand ihrer E-Mail-Adresse zugeordnet. Verwenden LDAP und SAML nicht dieselbe E-Mail-Adresse?

Die E-Mail-Adresse ist dieselbe. Wahrscheinlich muss ich prüfen, was im SAML-Payload enthalten ist.

Danke für den Hinweis. Ich werde das prüfen.

Ich erhalte folgende Fehlermeldung:

Started POST "/auth/saml" for 188.114.103.216 at 2020-08-04 16:46:20 +0000
(saml) Request phase initiated.
Started POST "/auth/saml/callback" for 188.114.103.216 at 2020-08-04 16:46:21 +0000
(saml) Callback phase initiated.
Processing by Users::OmniauthCallbacksController#complete as HTML
  Parameters: {"SAMLResponse"=>"........", "RelayState"=>"", "provider"=>"saml"}
Completed 422 Unprocessable Entity in 16ms (ActiveRecord: 0.0ms | Allocations: 4546)
ActiveRecord::RecordInvalid (Validation failed: Primary email is invalid.)
lib/distributed_mutex.rb:33:in `block in synchronize'
lib/distributed_mutex.rb:29:in `synchronize'
lib/distributed_mutex.rb:29:in `synchronize'
lib/distributed_mutex.rb:14:in `synchronize'
app/controllers/users/omniauth_callbacks_controller.rb:37:in `complete'
app/controllers/application_controller.rb:350:in `block in with_resolved_locale'
app/controllers/application_controller.rb:350:in `with_resolved_locale'
lib/middleware/omniauth_bypass_middleware.rb:47:in `call'
lib/content_security_policy/middleware.rb:12:in `call'
lib/middleware/anonymous_cache.rb:328:in `call'
config/initializers/100-quiet_logger.rb:19:in `call'
config/initializers/100-silence_logger.rb:31:in `call'
lib/middleware/enforce_hostname.rb:22:in `call'
lib/middleware/request_tracker.rb:176:in `call'
Failed to handle exception in exception app middleware : Validation failed: Primary email is invalid.

Ich habe den Payload der SAML-Antwort überprüft, und er sieht wie folgt aus (einige Daten wurden aus offensichtlichen Gründen entfernt):

<?xml version="1.0" encoding="UTF-8"?>
<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xs="http://www.w3.org/2001/XMLSchema" Destination="https://example.com/auth/saml/callback" ID="id123" IssueInstant="2020-08-04T16:39:45.888Z" Version="2.0">
   <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://www.okta.com/xyz</saml2:Issuer>
   <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:SignedInfo>
         <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
         <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
         <ds:Reference URI="#id123">
            <ds:Transforms>
               <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
               <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                  <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs" />
               </ds:Transform>
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
            <ds:DigestValue>....</ds:DigestValue>
         </ds:Reference>
      </ds:SignedInfo>
      <ds:SignatureValue>...</ds:SignatureValue>
      <ds:KeyInfo>
         <ds:X509Data>
            <ds:X509Certificate>...</ds:X509Certificate>
         </ds:X509Data>
      </ds:KeyInfo>
   </ds:Signature>
   <saml2p:Status>
      <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
   </saml2p:Status>
   <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="id123" IssueInstant="2020-08-04T16:39:45.888Z" Version="2.0">
      <saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://www.okta.com/xyz</saml2:Issuer>
      <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
         <ds:SignedInfo>
            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
            <ds:Reference URI="#id123">
               <ds:Transforms>
                  <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                  <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                     <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs" />
                  </ds:Transform>
               </ds:Transforms>
               <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
               <ds:DigestValue>...</ds:DigestValue>
            </ds:Reference>
         </ds:SignedInfo>
         <ds:SignatureValue>...</ds:SignatureValue>
         <ds:KeyInfo>
            <ds:X509Data>
               <ds:X509Certificate>...</ds:X509Certificate>
            </ds:X509Data>
         </ds:KeyInfo>
      </ds:Signature>
      <saml2:Subject>
         <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">my.name</saml2:NameID>
         <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
            <saml2:SubjectConfirmationData NotOnOrAfter="2020-08-04T16:44:45.888Z" Recipient="https://example.com/auth/saml/callback" />
         </saml2:SubjectConfirmation>
      </saml2:Subject>
      <saml2:Conditions NotBefore="2020-08-04T16:34:45.888Z" NotOnOrAfter="2020-08-04T16:44:45.888Z">
         <saml2:AudienceRestriction>
            <saml2:Audience>https://example.com</saml2:Audience>
         </saml2:AudienceRestriction>
      </saml2:Conditions>
      <saml2:AuthnStatement AuthnInstant="2020-08-04T06:53:32.462Z" SessionIndex="id789">
         <saml2:AuthnContext>
            <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
         </saml2:AuthnContext>
      </saml2:AuthnStatement>
      <saml2:AttributeStatement>
         <saml2:Attribute Name="screenName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
            <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">my.name@example.com</saml2:AttributeValue>
         </saml2:Attribute>
      </saml2:AttributeStatement>
   </saml2:Assertion>
</saml2p:Response>

Habt ihr eine Idee?

Vielen Dank,
AB

Es sieht also so aus, als ob dein SAML die E-Mail-Adresse nicht korrekt beendet? Oder du schaust im falschen Feld nach?

Das Problem besteht darin, dass mein Okta/SAML den Benutzernamen und nicht die E-Mail-Adresse in diesem Feld sendet:

<saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">my.name</saml2:NameID>

Ich habe es behoben, indem ich ein neues Attribut namens email hinzugefügt und das Projekt geforkt habe, um result.mail einzurichten, indem ich es aus diesem neuen Attribut lese (falls vorhanden).

Ich werde einen Pull-Request erstellen.

Vielen Dank,
AB