SAML 2.0 101
- Overview
- 术语对比
- 主要差异
- For Beginners
- For Advancers
- SAML Connector的常见配置(南向对接SAML)
- App支持SAML SSO的配置(北向对接SAML)
SAML 2.0 101
Overview
SAML 2.0是一个和OAuth2/OIDC类似的,都是
- 中心化的信任体系
- 基于Web
- 标准SSO协议
- SAML基于XML, OAuth2是json
术语对比
SAML和OIDC中的经常用到的一些术语做一些比较:
SAML | OIDC | Comment |
---|---|---|
Service Provider → SP | Relying Party → RP | |
Identity Provider → IDP | Identity Provider → IDP | |
AuthnRequest | Authorize | |
RelayState | State | |
Assertion Consuming Service → ACS | Redirect_URI | |
Assertion/Attribute | ID Token | |
Claim | Claim | |
Metadata | .well-known | SAML中的Metadata是双向的,即SP和IDP都有.而OIDC中只有IDP才有.well-known |
Binding | N/A | SAML中的Binding代表: SP用什么样的方式把AuthnRequest发给IDP,以及IDP用什么样的方式把AuthnResponse发给SP |
主要差异
SAML | OIDC | Comment |
---|---|---|
XML | JSON | SAML中AuthnRequest以及AuthnResponse都是XML格式的, OIDC的payload则是JSON的 |
Encryption/Signature | Encryption/Signature | SAML中的AuthnRequest以及AuthnResponse都可以做签名和加密(xml-sig/xml-enc), OIDC中的登录请求是不加密和签名的,只有返回的ID Token可以进行加密/签名 |
不支持offline access | 支持offline access | |
无consent页面 | 有consent |
For Beginners
如果之前对SAML没有任何概念,可以看一下如下的扫盲介绍,
- SAML for Web Developers: 基本概念,基本流程
For Advancers
进阶阶段可以看一下,
- Technical Overview: OASIS出品,较为抽象的介绍了SAML协议的各个组成部分以及常见的用户使用场景
- SAML协议很庞大,很灵活,但是灵活的背后是引入了更多的复杂性以及可能性。这里是一个建议SAML实现的最小集合
SAML Connector的常见配置(南向对接SAML)
这种场景下,idphub作为SAML的一个SP, 去南向的SAML IDP中做身份认证。
上文提到SAML的Metadata是双向的,意味着我们需要:
- 在Connector中配置该南向IDP的Metadata
- 在南向IDP中配置Connector作为SAML SP的Metadata
通常情况下,有两种方式来配置Metadata,
- 配一个Metadata的URL, IDP/SP通过这个URL去获取Metadata的配置信息
- 不用Metadata URL, 直接配置Metadata中的信息
如下实现基于第二种配置方式, 当创建一个SAML Connector时,通常情况下用到的配置参见下表(参见idp/saml.go → SAMLConfig)
属性名称 | 是否必填 | 缺省值 | 解释 |
---|---|---|---|
sso_url | Y | N/A | SP通过这个URL给IDP发起AuthnRequest请求 |
protocol_binding | N | HTTP-POST | SP通过POST表单的方式发送AuthnRequest请求 |
name_id_policy_format | N | urn:oasis:names:tc:SAML:2.0:nameid-format:persistent | SP请求用户唯一标识的格式,支持如下三种: urn:oasis:names:tc:SAML:2.0:nameid-format:persistent urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress urn:oasis:names:tc:SAML:2.0:nameid-format:transient |
sig_cert | N | N/A | IDP的签名证书(pem格式),用于验证AuthnResponse的签名 |
insecure_skip_sig_validation | N | false | 不校验AuthnResponse的签名au |
authn_template | N | {} | 没实现,目的是通过这个模板来构建AuthnRequest |
AuthnResponse的加密 | N | 未实现,即我们不支持加密的AuthnResponse |
留给大家的问题: 为什么上面的配置没有ACS? SAML IDP的AuthnResponse发往哪里??
比如,
{
"name": "samlidp",
"display_name":"saml idp",
"category":"ENT",
"type":"SAML",
"description":"saml idp",
"meta": {
"entity_issuer" : "http://localhost:8080/samlp/metadata?connection=samlidp",
"sso_issuer": "https://capriza.github.io/samling/samling.html",
"sso_url":"https://capriza.github.io/samling/samling.html",
"protocol_binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect",
"insecure_skip_sig_validation": false,
"name_id_policy_format" : "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
"authn_template": "",
"attrs_mapping": {
"email":"email",
"name":"name",
"uid": "username",
"groups": "groups",
"groups_delim": ","
},
"sig_cert": "-----BEGIN CERTIFICATE-----\nMIICpzCCAhACCQDuFX0Db5iljDANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMC\nVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCVBhbG8gQWx0bzEQMA4G\n A1UECgwHU2FtbGluZzEPMA0GA1UECwwGU2FsaW5nMRQwEgYDVQQDDAtjYXByaXph\nLmNvbTEmMCQGCSqGSIb3DQEJARYXZW5naW5lZXJpbmdAY2Fwcml6YS5jb20wHhcN\nMTgwNTE1MTgxMTEwWhcNMjgwNTEyMTgxMTEwWjCBlzELMAkGA1UEBhMCVVMxEzAR\nBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCVBhbG8gQWx0bzEQMA4GA1UECgwH\nU2FtbGluZzEPMA0GA1UECwwGU2FsaW5nMRQwEgYDVQQDDAtjYXByaXphLmNvbTEm\nMCQGCSqGSIb3DQEJARYXZW5naW5lZXJpbmdAY2Fwcml6YS5jb20wgZ8wDQYJKoZI\nhvcNAQEBBQADgY0AMIGJAoGBAJEBNDJKH5nXr0hZKcSNIY1l4HeYLPBEKJLXyAno\nFTdgGrvi40YyIx9lHh0LbDVWCgxJp21BmKll0CkgmeKidvGlr3FUwtETro44L+Sg\nmjiJNbftvFxhNkgA26O2GDQuBoQwgSiagVadWXwJKkodH8tx4ojBPYK1pBO8fHf3\nwOnxAgMBAAEwDQYJKoZIhvcNAQELBQADgYEACIylhvh6T758hcZjAQJiV7rMRg+O\nmb68iJI4L9f0cyBcJENR+1LQNgUGyFDMm9Wm9o81CuIKBnfpEE2Jfcs76YVWRJy5\nxJ11GFKJJ5T0NEB7txbUQPoJOeNoE736lF5vYw6YKp8fJqPW0L2PLWe9qTn8hxpd\nnjo3k6r5gXyl8tk=\n-----END CERTIFICATE-----\n"
}
}
App支持SAML SSO的配置(北向对接SAML)
这种场景下,App扮演的是SAML SP的角色,idphub扮演的是SAML IDP.
当一个App需要用SAML协议来做单点登录的时候,通常的配置包括(参见app.go, endpoint/saml.go)
属性名称 | 是否必填 | 缺省值 | 解释 |
---|---|---|---|
acs | Y | idphub把AuthnResponse发往acs指定的URL, App通过这个url来消费SAML Assertion | |
mappings | N | {} | idphub的user的model映射成AuthnResponse的model |
meta | N | {} | 用于构建AuthnResponse,知名属性名包括, audience, recipient,destination |
以bitbucket对接SAML SSO的配置为例,
{
"client_id": "bitbucket",
"client_name": "Bitbucket",
"application_type":"web",
"description":"bitbucket",
"redirect_uris": ["http://localhost:8081/example"],
"trusted_peers":[],
"id_token_exp":36000,
"access_token_exp": 3600,
"refresh_token_exp": 360000,
"skip_approval": false,
"logo_uri": "http://example.com/logo.png",
"bound_connectors": ["localidp"],
"saml": {
"acs": "http://bitbucket.toi.local:8080/plugins/servlet/saml/auth",
"mappings":{
"uid": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
"email": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
},
"meta": {
"audience": "http://bitbucket.toi.local:8080",
"recipient":"http://bitbucket.toi.local:8080/plugins/servlet/saml/auth",
"destination":"http://bitbucket.toi.local:8080/plugins/servlet/saml/auth"
}
}
}
Written on February 20, 2019