Zum Hauptinhalt springen

Übersicht

Casdoor kann jetzt als SAML IdP verwendet werden. Bis zu diesem Punkt hat Casdoor die Hauptfunktionen von SAML 2.0 unterstützt.

Konfiguration im SP

Im Allgemeinen benötigt der SP drei erforderliche Felder: Single Sign-On, Issuer und Öffentliches Zertifikat. Die meisten SPs können diese Felder durch Hochladen der XML-Metadatendatei oder der XML-Metadaten-URL zur automatischen Vervollständigung erhalten.

Die Metadaten des SAML-Endpunkts in Casdoor sind <Endpunkt von Casdoor>/api/saml/metadata?application=admin/<Anwendungsname>. Nehmen wir an, der Endpunkt von Casdoor ist https://door.casdoor.com, und es enthält eine Anwendung namens app-built-in. Der XML-Metadaten-Endpunkt wird sein:

https://door.casdoor.com/api/saml/metadata?application=admin/app-built-in

Sie können die Metadaten auch auf der Anwendungsbearbeitungsseite finden. Klicken Sie auf die Schaltfläche, um die URL zu kopieren und fügen Sie sie in den Browser ein, um die XML-Metadaten herunterzuladen.

Metadaten

Konfiguration in Casdoor IdP

Casdoor unterstützt sowohl GET als auch POST SAMLResponse. Casdoor muss wissen, welche Arten von Anfragen der SP unterstützt, wenn Casdoor die SAMLResponse an den SP sendet. Sie müssen die Anwendung in Casdoor basierend auf dem von Ihrem SP unterstützten SAMLResponse-Typ konfigurieren.

Info

Wenn Sie die Antwort-URL ausfüllen, sendet Casdoor die SAMLResponse per POST-Anfrage. Wenn die Antwort-URL leer ist, verwendet Casdoor eine GET-Anfrage. Sie fragen sich vielleicht, wie Casdoor die Antwort-URL des SP kennt, wenn die Antwort-URL leer ist. Tatsächlich kann Casdoor die URL namens AssertionConsumerServiceURL durch Parsen der SAMLRequest erhalten und die Anfrage mit SAMLResponse an AssertionConsumerServiceURL senden. Die Antwort-URL überschreibt die AssertionConsumerServiceURL in SAMLRequest.

  • Antwort-URL: Geben Sie die URL des ACS ein, der die SAML-Antwort überprüft.

    Antwort-URL

  • Weiterleitungs-URL: Geben Sie einen eindeutigen Namen ein. Dies kann in Ihrem SP als Audience oder Entity ID bezeichnet werden. Stellen Sie sicher, dass Sie hier dieselbe Weiterleitungs-URL ausfüllen wie in Ihrem SP.

    Entity ID

Benutzerprofil

Nach erfolgreichem Einloggen hat das Benutzerprofil in der zurückgegebenen SAMLResponse von Casdoor drei Felder. Die Attribute im XML und die Attribute des Benutzers in Casdoor werden wie folgt zugeordnet:

XML-AttributnameBenutzerfeld
E-Mailemail
AnzeigenamedisplayName
Namename

Siehe https://en.wikipedia.org/wiki/SAML_2.0 für weitere Informationen über SAML und seine verschiedenen Versionen.

Ein Beispiel

gosaml2 ist eine SAML 2.0-Implementierung für Dienstanbieter basierend auf etree und goxmldsig, einer reinen Go-Implementierung von XML-Digitalsignaturen. Wir verwenden diese Bibliothek, um SAML 2.0 in Casdoor wie unten gezeigt zu testen.

Nehmen wir an, Sie können auf Casdoor über http://localhost:7001/ zugreifen, und Ihr Casdoor enthält eine Anwendung namens app-built-in, die zu einer Organisation namens built-in gehört. Die URLs http://localhost:6900/acs/example und http://localhost:6900/saml/acs/example sollten zu den Weiterleitungs-URLs in app-built-in hinzugefügt werden.

import (
"crypto/x509"
"fmt"
"net/http"

"io/ioutil"

"encoding/base64"
"encoding/xml"

saml2 "github.com/russellhaering/gosaml2"
"github.com/russellhaering/gosaml2/types"
dsig "github.com/russellhaering/goxmldsig"
)

func main() {
res, err := http.Get("http://localhost:7001/api/saml/metadata?application=admin/app-built-in")
if err != nil {
panic(err)
}

rawMetadata, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err)
}

metadata := &types.EntityDescriptor{}
err = xml.Unmarshal(rawMetadata, metadata)
if err != nil {
panic(err)
}

certStore := dsig.MemoryX509CertificateStore{
Roots: []*x509.Certificate{},
}

for _, kd := range metadata.IDPSSODescriptor.KeyDescriptors {
for idx, xcert := range kd.KeyInfo.X509Data.X509Certificates {
if xcert.Data == "" {
panic(fmt.Errorf("metadata certificate(%d) must not be empty", idx))
}
certData, err := base64.StdEncoding.DecodeString(xcert.Data)
if err != nil {
panic(err)
}

idpCert, err := x509.ParseCertificate(certData)
if err != nil {
panic(err)
}

certStore.Roots = append(certStore.Roots, idpCert)
}
}

randomKeyStore := dsig.RandomKeyStoreForTest()

sp := &saml2.SAMLServiceProvider{
IdentityProviderSSOURL: metadata.IDPSSODescriptor.SingleSignOnServices[0].Location,
IdentityProviderIssuer: metadata.EntityID,
ServiceProviderIssuer: "http://localhost:6900/acs/example",
AssertionConsumerServiceURL: "http://localhost:6900/v1/_saml_callback",
SignAuthnRequests: true,
AudienceURI: "http://localhost:6900/saml/acs/example",
IDPCertificateStore: &certStore,
SPKeyStore: randomKeyStore,
}

http.HandleFunc("/v1/_saml_callback", func(rw http.ResponseWriter, req *http.Request) {
err := req.ParseForm()
if err != nil {
rw.WriteHeader(http.StatusBadRequest)
return
}
samlReponse := req.URL.Query().Get("SAMLResponse")
assertionInfo, err := sp.RetrieveAssertionInfo(samlReponse)
if err != nil {
fmt.Println(err)
rw.WriteHeader(http.StatusForbidden)
return
}
fmt.Println(assertionInfo)
if assertionInfo.WarningInfo.InvalidTime {
fmt.Println("here12:", assertionInfo.WarningInfo.InvalidTime)
rw.WriteHeader(http.StatusForbidden)
return
}

if assertionInfo.WarningInfo.NotInAudience {
fmt.Println(assertionInfo)
fmt.Println("here13:", assertionInfo.WarningInfo.NotInAudience)
rw.WriteHeader(http.StatusForbidden)
return
}

fmt.Fprintf(rw, "NameID: %s\n", assertionInfo.NameID)

fmt.Fprintf(rw, "Assertions:\n")

for key, val := range assertionInfo.Values {
fmt.Fprintf(rw, " %s: %+v\n", key, val)
}
fmt.Println(assertionInfo.Values.Get("FirstName"))
fmt.Fprintf(rw, "\n")

fmt.Fprintf(rw, "Warnings:\n")
fmt.Fprintf(rw, "%+v\n", assertionInfo.WarningInfo)
})

println("Visit this URL To Authenticate:")
authURL, err := sp.BuildAuthURL("")
if err != nil {
panic(err)
}

println(authURL)

println("Supply:")
fmt.Printf(" SP ACS URL : %s\n", sp.AssertionConsumerServiceURL)

err = http.ListenAndServe(":6900", nil)
if err != nil {
panic(err)
}
}

Führen Sie den obigen Code aus, und die Konsole zeigt die folgende Nachricht an.

Visit this URL To Authenticate:
http://localhost:7001/login/saml/authorize/admin/app-built-in?SAMLRequest=lFVbk6K8Fv0rFvNo2QR...
Supply:
SP ACS URL : http://localhost:6900/v1/_saml_callback

Klicken Sie auf die URL, um sich zu authentifizieren, und die Anmeldeseite von Casdoor wird angezeigt.

Anmeldung

Nach der Authentifizierung erhalten Sie die Antwortnachrichten wie unten gezeigt.

Antwort