要求

要想使用 ADFS 登陆到 Seafile,需要以下组件:

1、安装了 ADFS 的windows服务器。安装 ADFS 和相关配置详情请参考 本文

2、对于 ADFS 服务器的SSL有效证书,在这里我们使用 adfs-server.adfs.com 作为域名示例。

3、对于 seafile 服务器的SSL有效证书,在这里我们使用 demo.seafile.com 作为域名示例。

准备证书文件

1、SP(Service Provider) 的 x.509 证书

可以通过以下方式获取:

  1. openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout sp.key -out sp.crt

x.509 证书用来签署和加密诸如SAML的NameID和Metadata等元素。

然后将这两个文件复制到 /seahub-data/certs。如果证书文件夹不存在,请创建它。

2、IdP(Identity Provider) 的 x.509 证书

  1. 登陆到 ADFS 服务器并且打开 ADFS 管理。

  2. 双击 Service 并选择 Certificates

  3. 导出 Token-Signing 证书:

    1. 右击证书并选择 View Certificate
    2. 选择 Details 选项卡。
    3. 单击 Copy to File (选择 DER encoded binary X.509)。
  4. 将此证书转换为PEM格式,重命名为 idp.crt

  5. 复制它到 /seahub-data/certs

准备 IdP 元数据文件

  1. 打开 https://adfs-server.adfs.com/federationmetadata/2007-06/federationmetadata.xml

  2. 保存这个 xml 文件,重命名为 idp_federation_metadata.xml

  3. 复制它到 /seahub-data/certs

在 seafile 服务器上安装

  • 对于 Ubuntu 16.04
    1. sudo apt install libxmlsec1
    2. sudo pip install cryptography djangosaml2

配置seafile

添加以下配置到 seahub_settings.py

  1. from os import path
  2. import saml2
  3. import saml2.saml
  4. CERTS_DIR = '<seafile-install-path>/seahub-data/certs'
  5. SP_SERVICE_URL = 'https://demo.seafile.com'
  6. XMLSEC_BINARY = '/usr/local/bin/xmlsec1'
  7. ATTRIBUTE_MAP_DIR = '<seafile-install-path>/seafile-server-latest/seahub-extra/seahub_extra/adfs_auth/attribute-maps'
  8. SAML_ATTRIBUTE_MAPPING = {
  9. 'DisplayName': ('display_name', ),
  10. 'ContactEmail': ('contact_email', ),
  11. 'Deparment': ('department', ),
  12. 'Telephone': ('telephone', ),
  13. }
  14. ENABLE_ADFS_LOGIN = True
  15. EXTRA_AUTHENTICATION_BACKENDS = (
  16. 'seahub_extra.adfs_auth.backends.Saml2Backend',
  17. )
  18. SAML_USE_NAME_ID_AS_USERNAME = True
  19. LOGIN_REDIRECT_URL = '/saml2/complete/'
  20. SAML_CONFIG = {
  21. # full path to the xmlsec1 binary programm
  22. 'xmlsec_binary': XMLSEC_BINARY,
  23. 'allow_unknown_attributes': True,
  24. # your entity id, usually your subdomain plus the url to the metadata view
  25. 'entityid': SP_SERVICE_URL + '/saml2/metadata/',
  26. # directory with attribute mapping
  27. 'attribute_map_dir': ATTRIBUTE_MAP_DIR,
  28. # this block states what services we provide
  29. 'service': {
  30. # we are just a lonely SP
  31. 'sp' : {
  32. "allow_unsolicited": True,
  33. 'name': 'Federated Seafile Service',
  34. 'name_id_format': saml2.saml.NAMEID_FORMAT_EMAILADDRESS,
  35. 'endpoints': {
  36. # url and binding to the assetion consumer service view
  37. # do not change the binding or service name
  38. 'assertion_consumer_service': [
  39. (SP_SERVICE_URL + '/saml2/acs/',
  40. saml2.BINDING_HTTP_POST),
  41. ],
  42. # url and binding to the single logout service view
  43. # do not change the binding or service name
  44. 'single_logout_service': [
  45. (SP_SERVICE_URL + '/saml2/ls/',
  46. saml2.BINDING_HTTP_REDIRECT),
  47. (SP_SERVICE_URL + '/saml2/ls/post',
  48. saml2.BINDING_HTTP_POST),
  49. ],
  50. },
  51. # attributes that this project need to identify a user
  52. 'required_attributes': ["uid"],
  53. # attributes that may be useful to have but not required
  54. 'optional_attributes': ['eduPersonAffiliation', ],
  55. # in this section the list of IdPs we talk to are defined
  56. 'idp': {
  57. # we do not need a WAYF service since there is
  58. # only an IdP defined here. This IdP should be
  59. # present in our metadata
  60. # the keys of this dictionary are entity ids
  61. 'https://adfs-server.adfs.com/federationmetadata/2007-06/federationmetadata.xml': {
  62. 'single_sign_on_service': {
  63. saml2.BINDING_HTTP_REDIRECT: 'https://adfs-server.adfs.com/adfs/ls/idpinitiatedsignon.aspx',
  64. },
  65. 'single_logout_service': {
  66. saml2.BINDING_HTTP_REDIRECT: 'https://adfs-server.adfs.com/adfs/ls/?wa=wsignout1.0',
  67. },
  68. },
  69. },
  70. },
  71. },
  72. # where the remote metadata is stored
  73. 'metadata': {
  74. 'local': [path.join(CERTS_DIR, 'idp_federation_metadata.xml')],
  75. },
  76. # set to 1 to output debugging information
  77. 'debug': 1,
  78. # Signing
  79. 'key_file': '',
  80. 'cert_file': path.join(CERTS_DIR, 'certs/idp.crt'), # from IdP
  81. # Encryption
  82. 'encryption_keypairs': [{
  83. 'key_file': path.join(CERTS_DIR, 'certs/sp.key'), # private part
  84. 'cert_file': path.join(CERTS_DIR, 'certs/sp.crt'), # public part
  85. }],
  86. 'valid_for': 24, # how long is our metadata valid
  87. }

配置 ADFS 服务

  1. 添加 Relying Party Trust

    Relying Party Trust 是 Seafile 和 ADFS 之间的连接。

    1. 登陆到 ADFS 服务器并打开 ADFS 管理界面。

    2. 双击 Trust Relationships,然后右键 Relying Party Trusts,选择 Add Relying Party Trust…

    3. 选择 Import data about the relying party published online or one a local network,在 Federation metadata address 中输入 https://demo.seafile.com/saml2/metadata/

    4. 然后 Next 直到 Finish

  2. 添加 Relying Party Claim Rules

    Relying Party Claim Rules 是用于windows域中seafile和用户的通信。

    Important:在windows域中的用户必须要设置了 E-mail 值。

    1. 右键点击 relying party trust 并且选择 Edit Claim Rules…

    2. 在 Issuance Transform Rules Add Rules…

    3. 选择 Send LDAP Attribute as Claims 作为申请规则模版来用。

    4. 给 claim 一个名称,例如:LDAP Attributes。

    5. 将 Attribute Store 设置为 Active Directory,LDAP Attribute 设置为 E-Mail-Addresses,Outgoing Claim Type 设置为 E-mail Address

    6. 选择 Finish

    7. 再次单击 Add Rule…

    8. 选择 Transform an Incoming Claim

    9. 给它一个名字例如:Email to Name ID

    10. 输入的 claim 类型应该是 E-mail Address (它必须跟 rule #1 中的Outgoing Claim Type 相匹配)。

    11. Outgoing claim 的类型是 Name ID (这是seafile配置策略中的要求 'name_id_format': saml2.saml.NAMEID_FORMAT_EMAILADDRESS)。

    12. Outgoing name ID 格式为 Email

    13. 通过所有的 claim 的值 并且单击 Finish

测试

重启服务后,你可以打开一个web浏览器并且输入 https://demo.seafile.com,在登陆对话框中应该有一个 adfs 按钮。单击该按钮将重定向到 ADFS 服务器(adfs-server.adfs.com),如果用户名密码正确,你将被重定向到seafile主页。

对于descktop客户端,只需要在”Add a new account”窗口点击”Shibboleth Login”,输入 https://demo.seafile.com,单击 OK 按钮将会打开一个新的窗口显示ADFS服务的登录页面,如果用户名和密码正确,窗口将关闭并显示seafile资料库面板。