sso_mapping_providers.html 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. <!DOCTYPE HTML>
  2. <html lang="en" class="sidebar-visible no-js light">
  3. <head>
  4. <!-- Book generated using mdBook -->
  5. <meta charset="UTF-8">
  6. <title>SSO Mapping Providers - Synapse</title>
  7. <!-- Custom HTML head -->
  8. <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  9. <meta name="description" content="">
  10. <meta name="viewport" content="width=device-width, initial-scale=1">
  11. <meta name="theme-color" content="#ffffff" />
  12. <link rel="icon" href="favicon.svg">
  13. <link rel="shortcut icon" href="favicon.png">
  14. <link rel="stylesheet" href="css/variables.css">
  15. <link rel="stylesheet" href="css/general.css">
  16. <link rel="stylesheet" href="css/chrome.css">
  17. <link rel="stylesheet" href="css/print.css" media="print">
  18. <!-- Fonts -->
  19. <link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
  20. <link rel="stylesheet" href="fonts/fonts.css">
  21. <!-- Highlight.js Stylesheets -->
  22. <link rel="stylesheet" href="highlight.css">
  23. <link rel="stylesheet" href="tomorrow-night.css">
  24. <link rel="stylesheet" href="ayu-highlight.css">
  25. <!-- Custom theme stylesheets -->
  26. <link rel="stylesheet" href="docs/website_files/table-of-contents.css">
  27. <link rel="stylesheet" href="docs/website_files/remove-nav-buttons.css">
  28. <link rel="stylesheet" href="docs/website_files/indent-section-headers.css">
  29. <link rel="stylesheet" href="docs/website_files/version-picker.css">
  30. </head>
  31. <body>
  32. <!-- Provide site root to javascript -->
  33. <script type="text/javascript">
  34. var path_to_root = "";
  35. var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
  36. </script>
  37. <!-- Work around some values being stored in localStorage wrapped in quotes -->
  38. <script type="text/javascript">
  39. try {
  40. var theme = localStorage.getItem('mdbook-theme');
  41. var sidebar = localStorage.getItem('mdbook-sidebar');
  42. if (theme.startsWith('"') && theme.endsWith('"')) {
  43. localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
  44. }
  45. if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
  46. localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
  47. }
  48. } catch (e) { }
  49. </script>
  50. <!-- Set the theme before any content is loaded, prevents flash -->
  51. <script type="text/javascript">
  52. var theme;
  53. try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
  54. if (theme === null || theme === undefined) { theme = default_theme; }
  55. var html = document.querySelector('html');
  56. html.classList.remove('no-js')
  57. html.classList.remove('light')
  58. html.classList.add(theme);
  59. html.classList.add('js');
  60. </script>
  61. <!-- Hide / unhide sidebar before it is displayed -->
  62. <script type="text/javascript">
  63. var html = document.querySelector('html');
  64. var sidebar = 'hidden';
  65. if (document.body.clientWidth >= 1080) {
  66. try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
  67. sidebar = sidebar || 'visible';
  68. }
  69. html.classList.remove('sidebar-visible');
  70. html.classList.add("sidebar-" + sidebar);
  71. </script>
  72. <nav id="sidebar" class="sidebar" aria-label="Table of contents">
  73. <div class="sidebar-scrollbox">
  74. <ol class="chapter"><li class="chapter-item expanded affix "><li class="part-title">Introduction</li><li class="chapter-item expanded "><a href="welcome_and_overview.html">Welcome and Overview</a></li><li class="chapter-item expanded affix "><li class="part-title">Setup</li><li class="chapter-item expanded "><a href="setup/installation.html">Installation</a></li><li class="chapter-item expanded "><a href="postgres.html">Using Postgres</a></li><li class="chapter-item expanded "><a href="reverse_proxy.html">Configuring a Reverse Proxy</a></li><li class="chapter-item expanded "><a href="setup/forward_proxy.html">Configuring a Forward/Outbound Proxy</a></li><li class="chapter-item expanded "><a href="turn-howto.html">Configuring a Turn Server</a></li><li class="chapter-item expanded "><a href="delegate.html">Delegation</a></li><li class="chapter-item expanded affix "><li class="part-title">Upgrading</li><li class="chapter-item expanded "><a href="upgrade.html">Upgrading between Synapse Versions</a></li><li class="chapter-item expanded affix "><li class="part-title">Usage</li><li class="chapter-item expanded "><a href="federate.html">Federation</a></li><li class="chapter-item expanded "><a href="usage/configuration/index.html">Configuration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/configuration/config_documentation.html">Configuration Manual</a></li><li class="chapter-item expanded "><a href="usage/configuration/homeserver_sample_config.html">Homeserver Sample Config File</a></li><li class="chapter-item expanded "><a href="usage/configuration/logging_sample_config.html">Logging Sample Config File</a></li><li class="chapter-item expanded "><a href="structured_logging.html">Structured Logging</a></li><li class="chapter-item expanded "><a href="templates.html">Templates</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/index.html">User Authentication</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/index.html">Single-Sign On</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="openid.html">OpenID Connect</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/saml.html">SAML</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/cas.html">CAS</a></li><li class="chapter-item expanded "><a href="sso_mapping_providers.html" class="active">SSO Mapping Providers</a></li></ol></li><li class="chapter-item expanded "><a href="password_auth_providers.html">Password Auth Providers</a></li><li class="chapter-item expanded "><a href="jwt.html">JSON Web Tokens</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/refresh_tokens.html">Refresh Tokens</a></li></ol></li><li class="chapter-item expanded "><a href="CAPTCHA_SETUP.html">Registration Captcha</a></li><li class="chapter-item expanded "><a href="application_services.html">Application Services</a></li><li class="chapter-item expanded "><a href="server_notices.html">Server Notices</a></li><li class="chapter-item expanded "><a href="consent_tracking.html">Consent Tracking</a></li><li class="chapter-item expanded "><a href="user_directory.html">User Directory</a></li><li class="chapter-item expanded "><a href="message_retention_policies.html">Message Retention Policies</a></li><li class="chapter-item expanded "><a href="modules/index.html">Pluggable Modules</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="modules/writing_a_module.html">Writing a module</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="modules/spam_checker_callbacks.html">Spam checker callbacks</a></li><li class="chapter-item expanded "><a href="modules/third_party_rules_callbacks.html">Third-party rules callbacks</a></li><li class="chapter-item expanded "><a href="modules/presence_router_callbacks.html">Presence router callbacks</a></li><li class="chapter-item expanded "><a href="modules/account_validity_callbacks.html">Account validity callbacks</a></li><li class="chapter-item expanded "><a href="modules/password_auth_provider_callbacks.html">Password auth provider callbacks</a></li><li class="chapter-item expanded "><a href="modules/background_update_controller_callbacks.html">Background update controller callbacks</a></li><li class="chapter-item expanded "><a href="modules/account_data_callbacks.html">Account data callbacks</a></li><li class="chapter-item expanded "><a href="modules/porting_legacy_module.html">Porting a legacy module to the new interface</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="workers.html">Workers</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="synctl_workers.html">Using synctl with Workers</a></li><li class="chapter-item expanded "><a href="systemd-with-workers/index.html">Systemd</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="usage/administration/index.html">Administration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/administration/admin_api/index.html">Admin API</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="admin_api/account_validity.html">Account Validity</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/background_updates.html">Background Updates</a></li><li class="chapter-item expanded "><a href="admin_api/event_reports.html">Event Reports</a></li><li class="chapter-item expanded "><a href="admin_api/media_admin_api.html">Media</a></li><li class="chapter-item expanded "><a href="admin_api/purge_history_api.html">Purge History</a></li><li class="chapter-item expanded "><a href="admin_api/register_api.html">Register Users</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/registration_tokens.html">Registration Tokens</a></li><li class="chapter-item expanded "><a href="admin_api/room_membership.html">Manipulate Room Membership</a></li><li class="chapter-item expanded "><a href="admin_api/rooms.html">Rooms</a></li><li class="chapter-item expanded "><a href="admin_api/server_notices.html">Server Notices</a></li><li class="chapter-item expanded "><a href="admin_api/statistics.html">Statistics</a></li><li class="chapter-item expanded "><a href="admin_api/user_admin_api.html">Users</a></li><li class="chapter-item expanded "><a href="admin_api/version_api.html">Server Version</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/federation.html">Federation</a></li></ol></li><li class="chapter-item expanded "><a href="manhole.html">Manhole</a></li><li class="chapter-item expanded "><a href="metrics-howto.html">Monitoring</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/administration/monitoring/reporting_homeserver_usage_statistics.html">Reporting Homeserver Usage Statistics</a></li></ol></li><li class="chapter-item expanded "><a href="usage/administration/understanding_synapse_through_grafana_graphs.html">Understanding Synapse Through Grafana Graphs</a></li><li class="chapter-item expanded "><a href="usage/administration/useful_sql_for_admins.html">Useful SQL for Admins</a></li><li class="chapter-item expanded "><a href="usage/administration/database_maintenance_tools.html">Database Maintenance Tools</a></li><li class="chapter-item expanded "><a href="usage/administration/state_groups.html">State Groups</a></li><li class="chapter-item expanded "><a href="usage/administration/request_log.html">Request log format</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_faq.html">Admin FAQ</a></li><li class="chapter-item expanded "><div>Scripts</div></li></ol></li><li class="chapter-item expanded "><li class="part-title">Development</li><li class="chapter-item expanded "><a href="development/contributing_guide.html">Contributing Guide</a></li><li class="chapter-item expanded "><a href="code_style.html">Code Style</a></li><li class="chapter-item expanded "><a href="development/reviews.html">Reviewing Code</a></li><li class="chapter-item expanded "><a href="development/releases.html">Release Cycle</a></li><li class="chapter-item expanded "><a href="development/git.html">Git Usage</a></li><li class="chapter-item expanded "><div>Testing</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="development/demo.html">Demo scripts</a></li></ol></li><li class="chapter-item expanded "><a href="opentracing.html">OpenTracing</a></li><li class="chapter-item expanded "><a href="development/database_schema.html">Database Schemas</a></li><li class="chapter-item expanded "><a href="development/experimental_features.html">Experimental features</a></li><li class="chapter-item expanded "><a href="development/dependencies.html">Dependency management</a></li><li class="chapter-item expanded "><div>Synapse Architecture</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="development/synapse_architecture/cancellation.html">Cancellation</a></li><li class="chapter-item expanded "><a href="log_contexts.html">Log Contexts</a></li><li class="chapter-item expanded "><a href="replication.html">Replication</a></li><li class="chapter-item expanded "><a href="tcp_replication.html">TCP Replication</a></li></ol></li><li class="chapter-item expanded "><a href="development/internal_documentation/index.html">Internal Documentation</a></li><li><ol class="section"><li class="chapter-item expanded "><div>Single Sign-On</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="development/saml.html">SAML</a></li><li class="chapter-item expanded "><a href="development/cas.html">CAS</a></li></ol></li><li class="chapter-item expanded "><a href="development/room-dag-concepts.html">Room DAG concepts</a></li><li class="chapter-item expanded "><div>State Resolution</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="auth_chain_difference_algorithm.html">The Auth Chain Difference Algorithm</a></li></ol></li><li class="chapter-item expanded "><a href="media_repository.html">Media Repository</a></li><li class="chapter-item expanded "><a href="room_and_user_statistics.html">Room and User Statistics</a></li></ol></li><li class="chapter-item expanded "><div>Scripts</div></li><li class="chapter-item expanded affix "><li class="part-title">Other</li><li class="chapter-item expanded "><a href="deprecation_policy.html">Dependency Deprecation Policy</a></li><li class="chapter-item expanded "><a href="other/running_synapse_on_single_board_computers.html">Running Synapse on a Single-Board Computer</a></li></ol>
  75. </div>
  76. <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
  77. </nav>
  78. <div id="page-wrapper" class="page-wrapper">
  79. <div class="page">
  80. <div id="menu-bar-hover-placeholder"></div>
  81. <div id="menu-bar" class="menu-bar sticky bordered">
  82. <div class="left-buttons">
  83. <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
  84. <i class="fa fa-bars"></i>
  85. </button>
  86. <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
  87. <i class="fa fa-paint-brush"></i>
  88. </button>
  89. <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
  90. <li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
  91. <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
  92. <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
  93. <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
  94. <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
  95. </ul>
  96. <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
  97. <i class="fa fa-search"></i>
  98. </button>
  99. <div class="version-picker">
  100. <div class="dropdown">
  101. <div class="select">
  102. <span></span>
  103. <i class="fa fa-chevron-down"></i>
  104. </div>
  105. <input type="hidden" name="version">
  106. <ul class="dropdown-menu">
  107. <!-- Versions will be added dynamically in version-picker.js -->
  108. </ul>
  109. </div>
  110. </div>
  111. </div>
  112. <h1 class="menu-title">Synapse</h1>
  113. <div class="right-buttons">
  114. <a href="print.html" title="Print this book" aria-label="Print this book">
  115. <i id="print-button" class="fa fa-print"></i>
  116. </a>
  117. <a href="https://github.com/matrix-org/synapse" title="Git repository" aria-label="Git repository">
  118. <i id="git-repository-button" class="fa fa-github"></i>
  119. </a>
  120. <a href="https://github.com/matrix-org/synapse/edit/develop/docs/sso_mapping_providers.md" title="Suggest an edit" aria-label="Suggest an edit">
  121. <i id="git-edit-button" class="fa fa-edit"></i>
  122. </a>
  123. </div>
  124. </div>
  125. <div id="search-wrapper" class="hidden">
  126. <form id="searchbar-outer" class="searchbar-outer">
  127. <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
  128. </form>
  129. <div id="searchresults-outer" class="searchresults-outer hidden">
  130. <div id="searchresults-header" class="searchresults-header"></div>
  131. <ul id="searchresults">
  132. </ul>
  133. </div>
  134. </div>
  135. <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
  136. <script type="text/javascript">
  137. document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
  138. document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
  139. Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
  140. link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
  141. });
  142. </script>
  143. <div id="content" class="content">
  144. <main>
  145. <!-- Page table of contents -->
  146. <div class="sidetoc">
  147. <nav class="pagetoc"></nav>
  148. </div>
  149. <h1 id="sso-mapping-providers"><a class="header" href="#sso-mapping-providers">SSO Mapping Providers</a></h1>
  150. <p>A mapping provider is a Python class (loaded via a Python module) that
  151. works out how to map attributes of a SSO response to Matrix-specific
  152. user attributes. Details such as user ID localpart, displayname, and even avatar
  153. URLs are all things that can be mapped from talking to a SSO service.</p>
  154. <p>As an example, a SSO service may return the email address
  155. &quot;john.smith@example.com&quot; for a user, whereas Synapse will need to figure out how
  156. to turn that into a displayname when creating a Matrix user for this individual.
  157. It may choose <code>John Smith</code>, or <code>Smith, John [Example.com]</code> or any number of
  158. variations. As each Synapse configuration may want something different, this is
  159. where SAML mapping providers come into play.</p>
  160. <p>SSO mapping providers are currently supported for OpenID and SAML SSO
  161. configurations. Please see the details below for how to implement your own.</p>
  162. <p>It is up to the mapping provider whether the user should be assigned a predefined
  163. Matrix ID based on the SSO attributes, or if the user should be allowed to
  164. choose their own username.</p>
  165. <p>In the first case - where users are automatically allocated a Matrix ID - it is
  166. the responsibility of the mapping provider to normalise the SSO attributes and
  167. map them to a valid Matrix ID. The <a href="https://spec.matrix.org/latest/appendices/#user-identifiers">specification for Matrix
  168. IDs</a> has some
  169. information about what is considered valid.</p>
  170. <p>If the mapping provider does not assign a Matrix ID, then Synapse will
  171. automatically serve an HTML page allowing the user to pick their own username.</p>
  172. <p>External mapping providers are provided to Synapse in the form of an external
  173. Python module. You can retrieve this module from <a href="https://pypi.org">PyPI</a> or elsewhere,
  174. but it must be importable via Synapse (e.g. it must be in the same virtualenv
  175. as Synapse). The Synapse config is then modified to point to the mapping provider
  176. (and optionally provide additional configuration for it).</p>
  177. <h2 id="openid-mapping-providers"><a class="header" href="#openid-mapping-providers">OpenID Mapping Providers</a></h2>
  178. <p>The OpenID mapping provider can be customized by editing the
  179. <a href="usage/configuration/config_documentation.html#oidc_providers"><code>oidc_providers.user_mapping_provider.module</code></a>
  180. config option.</p>
  181. <p><code>oidc_providers.user_mapping_provider.config</code> allows you to provide custom
  182. configuration options to the module. Check with the module's documentation for
  183. what options it provides (if any). The options listed by default are for the
  184. user mapping provider built in to Synapse. If using a custom module, you should
  185. comment these options out and use those specified by the module instead.</p>
  186. <h3 id="building-a-custom-openid-mapping-provider"><a class="header" href="#building-a-custom-openid-mapping-provider">Building a Custom OpenID Mapping Provider</a></h3>
  187. <p>A custom mapping provider must specify the following methods:</p>
  188. <ul>
  189. <li><code>def __init__(self, parsed_config)</code>
  190. <ul>
  191. <li>Arguments:
  192. <ul>
  193. <li><code>parsed_config</code> - A configuration object that is the return value of the
  194. <code>parse_config</code> method. You should set any configuration options needed by
  195. the module here.</li>
  196. </ul>
  197. </li>
  198. </ul>
  199. </li>
  200. <li><code>def parse_config(config)</code>
  201. <ul>
  202. <li>This method should have the <code>@staticmethod</code> decoration.</li>
  203. <li>Arguments:
  204. <ul>
  205. <li><code>config</code> - A <code>dict</code> representing the parsed content of the
  206. <code>oidc_providers.user_mapping_provider.config</code> homeserver config option.
  207. Runs on homeserver startup. Providers should extract and validate
  208. any option values they need here.</li>
  209. </ul>
  210. </li>
  211. <li>Whatever is returned will be passed back to the user mapping provider module's
  212. <code>__init__</code> method during construction.</li>
  213. </ul>
  214. </li>
  215. <li><code>def get_remote_user_id(self, userinfo)</code>
  216. <ul>
  217. <li>Arguments:
  218. <ul>
  219. <li><code>userinfo</code> - A <code>authlib.oidc.core.claims.UserInfo</code> object to extract user
  220. information from.</li>
  221. </ul>
  222. </li>
  223. <li>This method must return a string, which is the unique, immutable identifier
  224. for the user. Commonly the <code>sub</code> claim of the response.</li>
  225. </ul>
  226. </li>
  227. <li><code>async def map_user_attributes(self, userinfo, token, failures)</code>
  228. <ul>
  229. <li>This method must be async.</li>
  230. <li>Arguments:
  231. <ul>
  232. <li><code>userinfo</code> - A <code>authlib.oidc.core.claims.UserInfo</code> object to extract user
  233. information from.</li>
  234. <li><code>token</code> - A dictionary which includes information necessary to make
  235. further requests to the OpenID provider.</li>
  236. <li><code>failures</code> - An <code>int</code> that represents the amount of times the returned
  237. mxid localpart mapping has failed. This should be used
  238. to create a deduplicated mxid localpart which should be
  239. returned instead. For example, if this method returns
  240. <code>john.doe</code> as the value of <code>localpart</code> in the returned
  241. dict, and that is already taken on the homeserver, this
  242. method will be called again with the same parameters but
  243. with failures=1. The method should then return a different
  244. <code>localpart</code> value, such as <code>john.doe1</code>.</li>
  245. </ul>
  246. </li>
  247. <li>Returns a dictionary with two keys:
  248. <ul>
  249. <li><code>localpart</code>: A string, used to generate the Matrix ID. If this is
  250. <code>None</code>, the user is prompted to pick their own username. This is only used
  251. during a user's first login. Once a localpart has been associated with a
  252. remote user ID (see <code>get_remote_user_id</code>) it cannot be updated.</li>
  253. <li><code>displayname</code>: An optional string, the display name for the user.</li>
  254. </ul>
  255. </li>
  256. </ul>
  257. </li>
  258. <li><code>async def get_extra_attributes(self, userinfo, token)</code>
  259. <ul>
  260. <li>
  261. <p>This method must be async.</p>
  262. </li>
  263. <li>
  264. <p>Arguments:</p>
  265. <ul>
  266. <li><code>userinfo</code> - A <code>authlib.oidc.core.claims.UserInfo</code> object to extract user
  267. information from.</li>
  268. <li><code>token</code> - A dictionary which includes information necessary to make
  269. further requests to the OpenID provider.</li>
  270. </ul>
  271. </li>
  272. <li>
  273. <p>Returns a dictionary that is suitable to be serialized to JSON. This
  274. will be returned as part of the response during a successful login.</p>
  275. <p>Note that care should be taken to not overwrite any of the parameters
  276. usually returned as part of the <a href="https://spec.matrix.org/latest/client-server-api/#post_matrixclientv3login">login response</a>.</p>
  277. </li>
  278. </ul>
  279. </li>
  280. </ul>
  281. <h3 id="default-openid-mapping-provider"><a class="header" href="#default-openid-mapping-provider">Default OpenID Mapping Provider</a></h3>
  282. <p>Synapse has a built-in OpenID mapping provider if a custom provider isn't
  283. specified in the config. It is located at
  284. <a href="https://github.com/matrix-org/synapse/blob/develop/synapse/handlers/oidc.py"><code>synapse.handlers.oidc.JinjaOidcMappingProvider</code></a>.</p>
  285. <h2 id="saml-mapping-providers"><a class="header" href="#saml-mapping-providers">SAML Mapping Providers</a></h2>
  286. <p>The SAML mapping provider can be customized by editing the
  287. <a href="docs/usage/configuration/config_documentation.html#saml2_config"><code>saml2_config.user_mapping_provider.module</code></a>
  288. config option.</p>
  289. <p><code>saml2_config.user_mapping_provider.config</code> allows you to provide custom
  290. configuration options to the module. Check with the module's documentation for
  291. what options it provides (if any). The options listed by default are for the
  292. user mapping provider built in to Synapse. If using a custom module, you should
  293. comment these options out and use those specified by the module instead.</p>
  294. <h3 id="building-a-custom-saml-mapping-provider"><a class="header" href="#building-a-custom-saml-mapping-provider">Building a Custom SAML Mapping Provider</a></h3>
  295. <p>A custom mapping provider must specify the following methods:</p>
  296. <ul>
  297. <li><code>def __init__(self, parsed_config, module_api)</code>
  298. <ul>
  299. <li>Arguments:
  300. <ul>
  301. <li><code>parsed_config</code> - A configuration object that is the return value of the
  302. <code>parse_config</code> method. You should set any configuration options needed by
  303. the module here.</li>
  304. <li><code>module_api</code> - a <code>synapse.module_api.ModuleApi</code> object which provides the
  305. stable API available for extension modules.</li>
  306. </ul>
  307. </li>
  308. </ul>
  309. </li>
  310. <li><code>def parse_config(config)</code>
  311. <ul>
  312. <li><strong>This method should have the <code>@staticmethod</code> decoration.</strong></li>
  313. <li>Arguments:
  314. <ul>
  315. <li><code>config</code> - A <code>dict</code> representing the parsed content of the
  316. <code>saml_config.user_mapping_provider.config</code> homeserver config option.
  317. Runs on homeserver startup. Providers should extract and validate
  318. any option values they need here.</li>
  319. </ul>
  320. </li>
  321. <li>Whatever is returned will be passed back to the user mapping provider module's
  322. <code>__init__</code> method during construction.</li>
  323. </ul>
  324. </li>
  325. <li><code>def get_saml_attributes(config)</code>
  326. <ul>
  327. <li><strong>This method should have the <code>@staticmethod</code> decoration.</strong></li>
  328. <li>Arguments:
  329. <ul>
  330. <li><code>config</code> - A object resulting from a call to <code>parse_config</code>.</li>
  331. </ul>
  332. </li>
  333. <li>Returns a tuple of two sets. The first set equates to the SAML auth
  334. response attributes that are required for the module to function, whereas
  335. the second set consists of those attributes which can be used if available,
  336. but are not necessary.</li>
  337. </ul>
  338. </li>
  339. <li><code>def get_remote_user_id(self, saml_response, client_redirect_url)</code>
  340. <ul>
  341. <li>Arguments:
  342. <ul>
  343. <li><code>saml_response</code> - A <code>saml2.response.AuthnResponse</code> object to extract user
  344. information from.</li>
  345. <li><code>client_redirect_url</code> - A string, the URL that the client will be
  346. redirected to.</li>
  347. </ul>
  348. </li>
  349. <li>This method must return a string, which is the unique, immutable identifier
  350. for the user. Commonly the <code>uid</code> claim of the response.</li>
  351. </ul>
  352. </li>
  353. <li><code>def saml_response_to_user_attributes(self, saml_response, failures, client_redirect_url)</code>
  354. <ul>
  355. <li>
  356. <p>Arguments:</p>
  357. <ul>
  358. <li><code>saml_response</code> - A <code>saml2.response.AuthnResponse</code> object to extract user
  359. information from.</li>
  360. <li><code>failures</code> - An <code>int</code> that represents the amount of times the returned
  361. mxid localpart mapping has failed. This should be used
  362. to create a deduplicated mxid localpart which should be
  363. returned instead. For example, if this method returns
  364. <code>john.doe</code> as the value of <code>mxid_localpart</code> in the returned
  365. dict, and that is already taken on the homeserver, this
  366. method will be called again with the same parameters but
  367. with failures=1. The method should then return a different
  368. <code>mxid_localpart</code> value, such as <code>john.doe1</code>.</li>
  369. <li><code>client_redirect_url</code> - A string, the URL that the client will be
  370. redirected to.</li>
  371. </ul>
  372. </li>
  373. <li>
  374. <p>This method must return a dictionary, which will then be used by Synapse
  375. to build a new user. The following keys are allowed:</p>
  376. <ul>
  377. <li><code>mxid_localpart</code> - A string, the mxid localpart of the new user. If this is
  378. <code>None</code>, the user is prompted to pick their own username. This is only used
  379. during a user's first login. Once a localpart has been associated with a
  380. remote user ID (see <code>get_remote_user_id</code>) it cannot be updated.</li>
  381. <li><code>displayname</code> - The displayname of the new user. If not provided, will default to
  382. the value of <code>mxid_localpart</code>.</li>
  383. <li><code>emails</code> - A list of emails for the new user. If not provided, will
  384. default to an empty list.</li>
  385. </ul>
  386. <p>Alternatively it can raise a <code>synapse.api.errors.RedirectException</code> to
  387. redirect the user to another page. This is useful to prompt the user for
  388. additional information, e.g. if you want them to provide their own username.
  389. It is the responsibility of the mapping provider to either redirect back
  390. to <code>client_redirect_url</code> (including any additional information) or to
  391. complete registration using methods from the <code>ModuleApi</code>.</p>
  392. </li>
  393. </ul>
  394. </li>
  395. </ul>
  396. <h3 id="default-saml-mapping-provider"><a class="header" href="#default-saml-mapping-provider">Default SAML Mapping Provider</a></h3>
  397. <p>Synapse has a built-in SAML mapping provider if a custom provider isn't
  398. specified in the config. It is located at
  399. <a href="https://github.com/matrix-org/synapse/blob/develop/synapse/handlers/saml.py"><code>synapse.handlers.saml.DefaultSamlMappingProvider</code></a>.</p>
  400. </main>
  401. <nav class="nav-wrapper" aria-label="Page navigation">
  402. <!-- Mobile navigation buttons -->
  403. <a rel="prev" href="usage/configuration/user_authentication/single_sign_on/cas.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
  404. <i class="fa fa-angle-left"></i>
  405. </a>
  406. <a rel="next" href="password_auth_providers.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
  407. <i class="fa fa-angle-right"></i>
  408. </a>
  409. <div style="clear: both"></div>
  410. </nav>
  411. </div>
  412. </div>
  413. <nav class="nav-wide-wrapper" aria-label="Page navigation">
  414. <a rel="prev" href="usage/configuration/user_authentication/single_sign_on/cas.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
  415. <i class="fa fa-angle-left"></i>
  416. </a>
  417. <a rel="next" href="password_auth_providers.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
  418. <i class="fa fa-angle-right"></i>
  419. </a>
  420. </nav>
  421. </div>
  422. <script type="text/javascript">
  423. window.playground_copyable = true;
  424. </script>
  425. <script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
  426. <script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
  427. <script src="searcher.js" type="text/javascript" charset="utf-8"></script>
  428. <script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script>
  429. <script src="highlight.js" type="text/javascript" charset="utf-8"></script>
  430. <script src="book.js" type="text/javascript" charset="utf-8"></script>
  431. <!-- Custom JS scripts -->
  432. <script type="text/javascript" src="docs/website_files/table-of-contents.js"></script>
  433. <script type="text/javascript" src="docs/website_files/version-picker.js"></script>
  434. <script type="text/javascript" src="docs/website_files/version.js"></script>
  435. </body>
  436. </html>