概要
Casdoorは現在、SAML IdPとして使用できます。 この時点まで、CasdoorはSAML 2.0の主要な機能をサポートしています。
SPでの設定
一般的に、SPはSingle Sign-On、Issuer、Public Certificateの3つの必須フィールドを要求します。 ほとんどのSPは、XMLメタデータファイルまたはXMLメタデータURLをアップロードすることでこれらのフィールドを自動補完で取得できます。
CasdoorのSAMLエンドポイントのメタデータは<Casdoorのエンドポイント>/api/saml/metadata?application=admin/<アプリケーション名>です。 Casdoorのエンドポイントがhttps://door.casdoor.comで、app-built-inというアプリケーションが含まれているとします。 XMLメタデータエンドポイントは以下の通りです:
https://door.casdoor.com/api/saml/metadata?application=admin/app-built-in
メタデータはアプリケーション編集ページでも見つけることができます。 ボタンをクリックしてURLをコピーし、ブラウザに貼り付けてXMLメタデータをダウンロードします。

Casdoor IdPでの設定
CasdoorはSAMLResponseのGETとPOSTの両方をサポートしています。 CasdoorがSPにSAMLResponseを送信する際、SPがサポートするリクエストの種類をCasdoorが知る必要があります。 SPがサポートするSAMLResponseタイプに基づいてCasdoorでアプリケーションを設定する必要があります。
Reply URLを入力すると、CasdoorはSAMLResponseをPOSTリクエストで送信します。 返信URLが空の場合、CasdoorはGETリクエストを使用します。 Reply URLが空の場合、CasdoorがSPのReply URLをどのように知るか疑問に思うかもしれません。 実際には、CasdoorはSAMLRequestを解析してAssertionConsumerServiceURLと呼ばれるURLを取得し、SAMLResponseをAssertionConsumerServiceURLに送信します。 Reply URLはSAMLRequest内のAssertionConsumerServiceURLを上書きします。
返信URL:SAMLレスポンスを検証するACSのURLを入力します。

リダイレクトURL:一意の名前を入力します。 これはSPでは
AudienceまたはEntity IDと呼ばれることがあります。 SPで使用するのと同じRedirect URLをここに入力してください。
SAML attributes
Some SP will require you to provide external attributes in SAML Response, you can add those in SAML attributes table. And you can insert user's field to it.
For examle
| 名前 | Name format | Value |
|---|---|---|
https://www.aliyun.com/SAML-Role/Attributes/RoleSessionName | Unspecified | $user.name |
https://www.aliyun.com/SAML-Role/Attributes/Role | Unspecified | acs:ram::1879818006829152:role/$user.roles,acs:ram::1879818006829152:saml-provider/testa |
will generate response with external saml:Attribute
<saml:Attribute Name="https://www.aliyun.com/SAML-Role/Attributes/RoleSessionName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml:AttributeValue xsi:type="xs:string">admi122n@outlook.com</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="https://www.aliyun.com/SAML-Role/Attributes/Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml:AttributeValue xsi:type="xs:string"> acs:ram::1879818006829152:role/role1,acs:ram::1879818006829152:saml-provider/testa</saml:AttributeValue>
<saml:AttributeValue xsi:type="xs:string"> acs:ram::1879818006829152:role/role2,acs:ram::1879818006829152:saml-provider/testa</saml:AttributeValue>
</saml:Attribute>
We only support insert $user.owner,$user.name,$user.email,$user.id,$user.phone,$user.roles,$user.permissions,$user.groups
ユーザープロファイル
正常にログインした後、Casdoorから返されるSAMLResponseのユーザープロファイルには3つのフィールドがあります。 XMLの属性とCasdoorのユーザーの属性は以下のようにマッピングされます:
| XML属性名 | ユーザーフィールド |
|---|---|
| メール | |
| 表示名 | displayName |
| Name | name |
SAMLとその異なるバージョンについての詳細は、https://en.wikipedia.org/wiki/SAML_2.0を参照してください。
例
gosaml2は、etreeとgoxmldsigに基づいたサービスプロバイダー向けのSAML 2.0実装で、XMLデジタル署名の純粋なGo実装です。 以下に示すように、このライブラリを使用してCasdoorでのSAML 2.0をテストします。
Casdoorにhttp://localhost:7001/を通じてアクセスでき、built-inという組織に属するapp-built-inというアプリケーションが含まれているとします。 URLhttp://localhost:6900/acs/exampleとhttp://localhost:6900/saml/acs/exampleはapp-built-inのリダイレクトURLに追加する必要があります。
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)
}
}
上記のコードを実行すると、コンソールに以下のメッセージが表示されます。
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
URLをクリックして認証すると、Casdoorのログインページが表示されます。

認証後、以下に示すような応答メッセージを受け取ります。
