概要
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のログインページが表示されます。
認証後、以下に示すような応答メッセージを受け取ります。