メインコンテンツにスキップ

概要

Casdoorは現在、SAML IdPとして使用できます。 この時点まで、CasdoorはSAML 2.0の主要な機能をサポートしています。

SPでの設定

一般的に、SPはSingle Sign-OnIssuerPublic 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はSAMLResponsePOSTリクエストで送信します。 返信URLが空の場合、CasdoorはGETリクエストを使用します。 Reply URLが空の場合、CasdoorがSPのReply URLをどのように知るか疑問に思うかもしれません。 実際には、CasdoorはSAMLRequestを解析してAssertionConsumerServiceURLと呼ばれるURLを取得し、SAMLResponseAssertionConsumerServiceURLに送信します。 Reply URLSAMLRequest内のAssertionConsumerServiceURLを上書きします。

  • 返信URL:SAMLレスポンスを検証するACSのURLを入力します。

    返信URL

  • リダイレクトURL:一意の名前を入力します。 これはSPではAudienceまたはEntity IDと呼ばれることがあります。 SPで使用するのと同じRedirect URLをここに入力してください。

    エンティティID

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 formatValue
https://www.aliyun.com/SAML-Role/Attributes/RoleSessionNameUnspecified$user.name
https://www.aliyun.com/SAML-Role/Attributes/RoleUnspecifiedacs: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属性名ユーザーフィールド
メールemail
表示名displayName
Namename

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/examplehttp://localhost:6900/saml/acs/exampleapp-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のログインページが表示されます。

ログイン

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

応答