Pular para o conteúdo principal

Visão Geral

Casdoor agora pode ser usado como um SAML IdP. Até este ponto, o Casdoor suportou as principais funcionalidades do SAML 2.0.

Configuração no SP

Em geral, o SP requer três campos obrigatórios: Single Sign-On, Issuer e Public Certificate. A maioria dos SPs pode obter esses campos fazendo o upload do arquivo de Metadados XML ou da URL de Metadados XML para preenchimento automático.

Os metadados do ponto de extremidade SAML no Casdoor são <Endpoint of casdoor>/api/saml/metadata?application=admin/<application name>. Suponha que o ponto de extremidade do Casdoor seja https://door.casdoor.com, e ele contém uma aplicação chamada app-built-in. O ponto de extremidade de Metadados XML será:

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

Você também pode encontrar os metadados na página de edição da aplicação. Clique no botão para copiar a URL e cole-a no navegador para baixar os Metadados XML.

metadados

Configuração no Casdoor IdP

Casdoor suporta tanto GET quanto POST SAMLResponse. O Casdoor precisa saber quais tipos de solicitações o SP suporta quando o Casdoor envia o SAMLResponse para o SP. Você precisa configurar a aplicação no Casdoor com base no tipo de SAMLResponse suportado pelo seu SP.

informação

Se você preencher a URL de Resposta, o Casdoor enviará o SAMLResponse por Solicitação POST. Se a URL de Resposta estiver vazia, o Casdoor usará a solicitação GET. Você pode se perguntar como o Casdoor sabe a URL de Resposta do SP se a URL de Resposta estiver vazia. Na verdade, o Casdoor pode obter a URL chamada AssertionConsumerServiceURL analisando o SAMLRequest e enviar a solicitação com SAMLResponse para AssertionConsumerServiceURL. A URL de Resposta substituirá a AssertionConsumerServiceURL no SAMLRequest.

  • URL de Resposta: Digite a URL do ACS que verifica a resposta SAML.

    URL de Resposta

  • URL de Redirecionamento: Digite um nome único. Isto pode ser chamado de Audience ou Entity ID no seu SP. Certifique-se de preencher a mesma URL de Redirecionamento aqui como no seu SP.

    Entity ID

Perfil do usuário

Após o login bem-sucedido, o perfil do usuário na SAMLResponse retornada do Casdoor tem três campos. Os atributos no XML e os atributos do usuário no Casdoor são mapeados da seguinte forma:

Nome do Atributo XMLCampo do usuário
Emailemail
DisplayNamedisplayName
Nomename

Veja https://en.wikipedia.org/wiki/SAML_2.0 para mais informações sobre SAML e suas diferentes versões.

Um exemplo

gosaml2 é uma implementação do SAML 2.0 para Provedores de Serviço baseada em etree e goxmldsig, uma implementação pura em Go de assinaturas digitais XML. Usamos esta biblioteca para testar o SAML 2.0 no Casdoor como mostrado abaixo.

Suponha que você possa acessar o Casdoor através de http://localhost:7001/, e seu Casdoor contém uma aplicação chamada app-built-in, que pertence a uma organização chamada built-in. As URLs, http://localhost:6900/acs/example e http://localhost:6900/saml/acs/example, devem ser adicionadas às URLs de Redirecionamento em app-built-in.

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)
}
}

Execute o código acima, e o console exibirá a seguinte mensagem.

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

Clique na URL para autenticar, e a página de login do Casdoor será exibida.

login

Após autenticar, você receberá as mensagens de resposta como mostrado abaixo.

resposta