mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-24 21:17:01 +01:00
486 lines
33 KiB
HTML
486 lines
33 KiB
HTML
<!DOCTYPE HTML>
|
|
<html lang="en" class="sidebar-visible no-js light">
|
|
<head>
|
|
<!-- Book generated using mdBook -->
|
|
<meta charset="UTF-8">
|
|
<title>Oauth2 - Kanidm Administration</title>
|
|
|
|
|
|
<!-- Custom HTML head -->
|
|
|
|
<meta name="description" content="">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="theme-color" content="#ffffff" />
|
|
|
|
<link rel="shortcut icon" href="../favicon.png">
|
|
<link rel="stylesheet" href="../css/variables.css">
|
|
<link rel="stylesheet" href="../css/general.css">
|
|
<link rel="stylesheet" href="../css/chrome.css">
|
|
<link rel="stylesheet" href="../css/print.css" media="print">
|
|
|
|
<!-- Fonts -->
|
|
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
|
<link rel="stylesheet" href="../fonts/fonts.css">
|
|
|
|
<!-- Highlight.js Stylesheets -->
|
|
<link rel="stylesheet" href="../highlight.css">
|
|
<link rel="stylesheet" href="../tomorrow-night.css">
|
|
<link rel="stylesheet" href="../ayu-highlight.css">
|
|
|
|
<!-- Custom theme stylesheets -->
|
|
|
|
</head>
|
|
<body>
|
|
<div id="body-container">
|
|
<!-- Provide site root to javascript -->
|
|
<script>
|
|
var path_to_root = "../";
|
|
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
|
</script>
|
|
|
|
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
|
<script>
|
|
try {
|
|
var theme = localStorage.getItem('mdbook-theme');
|
|
var sidebar = localStorage.getItem('mdbook-sidebar');
|
|
|
|
if (theme.startsWith('"') && theme.endsWith('"')) {
|
|
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
|
}
|
|
|
|
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
|
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
|
}
|
|
} catch (e) { }
|
|
</script>
|
|
|
|
<!-- Set the theme before any content is loaded, prevents flash -->
|
|
<script>
|
|
var theme;
|
|
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
|
if (theme === null || theme === undefined) { theme = default_theme; }
|
|
var html = document.querySelector('html');
|
|
html.classList.remove('no-js')
|
|
html.classList.remove('light')
|
|
html.classList.add(theme);
|
|
html.classList.add('js');
|
|
</script>
|
|
|
|
<!-- Hide / unhide sidebar before it is displayed -->
|
|
<script>
|
|
var html = document.querySelector('html');
|
|
var sidebar = null;
|
|
if (document.body.clientWidth >= 1080) {
|
|
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
|
sidebar = sidebar || 'visible';
|
|
} else {
|
|
sidebar = 'hidden';
|
|
}
|
|
html.classList.remove('sidebar-visible');
|
|
html.classList.add("sidebar-" + sidebar);
|
|
</script>
|
|
|
|
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
|
<div class="sidebar-scrollbox">
|
|
<ol class="chapter"><li class="chapter-item expanded "><a href="../intro.html"><strong aria-hidden="true">1.</strong> Introduction to Kanidm</a></li><li class="chapter-item expanded "><a href="../installing_the_server.html"><strong aria-hidden="true">2.</strong> Installing the Server</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../choosing_a_domain_name.html"><strong aria-hidden="true">2.1.</strong> Choosing a Domain Name</a></li><li class="chapter-item expanded "><a href="../prepare_the_server.html"><strong aria-hidden="true">2.2.</strong> Preparing for your Deployment</a></li><li class="chapter-item expanded "><a href="../server_configuration.html"><strong aria-hidden="true">2.3.</strong> Server Configuration and Install</a></li><li class="chapter-item expanded "><a href="../security_hardening.html"><strong aria-hidden="true">2.4.</strong> Platform Security Hardening</a></li><li class="chapter-item expanded "><a href="../server_update.html"><strong aria-hidden="true">2.5.</strong> Server Updates</a></li></ol></li><li class="chapter-item expanded "><a href="../client_tools.html"><strong aria-hidden="true">3.</strong> Client Tools</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../installing_client_tools.html"><strong aria-hidden="true">3.1.</strong> Installing client tools</a></li></ol></li><li class="chapter-item expanded "><li class="part-title">Administration</li><li class="chapter-item expanded "><a href="../administrivia.html"><strong aria-hidden="true">4.</strong> Administration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../accounts_and_groups.html"><strong aria-hidden="true">4.1.</strong> Accounts and Groups</a></li><li class="chapter-item expanded "><a href="../posix_accounts.html"><strong aria-hidden="true">4.2.</strong> POSIX Accounts and Groups</a></li><li class="chapter-item expanded "><a href="../backup_restore.html"><strong aria-hidden="true">4.3.</strong> Backup and Restore</a></li><li class="chapter-item expanded "><a href="../database_maint.html"><strong aria-hidden="true">4.4.</strong> Database Maintenance</a></li><li class="chapter-item expanded "><a href="../domain_rename.html"><strong aria-hidden="true">4.5.</strong> Domain Rename</a></li><li class="chapter-item expanded "><a href="../monitoring.html"><strong aria-hidden="true">4.6.</strong> Monitoring the platform</a></li><li class="chapter-item expanded "><a href="../password_quality.html"><strong aria-hidden="true">4.7.</strong> Password Quality and Badlisting</a></li><li class="chapter-item expanded "><a href="../recycle_bin.html"><strong aria-hidden="true">4.8.</strong> The Recycle Bin</a></li></ol></li><li class="chapter-item expanded "><li class="part-title">Services</li><li class="chapter-item expanded "><a href="../integrations/pam_and_nsswitch.html"><strong aria-hidden="true">5.</strong> PAM and nsswitch</a></li><li class="chapter-item expanded "><a href="../ssh_key_dist.html"><strong aria-hidden="true">6.</strong> SSH Key Distribution</a></li><li class="chapter-item expanded "><a href="../integrations/oauth2.html" class="active"><strong aria-hidden="true">7.</strong> Oauth2</a></li><li class="chapter-item expanded "><a href="../integrations/ldap.html"><strong aria-hidden="true">8.</strong> LDAP</a></li><li class="chapter-item expanded "><a href="../integrations/radius.html"><strong aria-hidden="true">9.</strong> RADIUS</a></li><li class="chapter-item expanded affix "><li class="part-title">Synchronisation</li><li class="chapter-item expanded "><a href="../sync/concepts.html"><strong aria-hidden="true">10.</strong> Concepts</a></li><li class="chapter-item expanded "><a href="../sync/freeipa.html"><strong aria-hidden="true">11.</strong> FreeIPA</a></li><li class="chapter-item expanded affix "><li class="part-title">Integration Examples</li><li class="chapter-item expanded "><a href="../examples/k8s_ingress_example.html"><strong aria-hidden="true">12.</strong> Kubernetes Ingress</a></li><li class="chapter-item expanded "><a href="../integrations/traefik.html"><strong aria-hidden="true">13.</strong> Traefik</a></li><li class="chapter-item expanded affix "><li class="part-title">Support</li><li class="chapter-item expanded "><a href="../troubleshooting.html"><strong aria-hidden="true">14.</strong> Troubleshooting</a></li><li class="chapter-item expanded "><a href="../frequently_asked_questions.html"><strong aria-hidden="true">15.</strong> Frequently Asked Questions</a></li><li class="chapter-item expanded "><a href="../glossary.html"><strong aria-hidden="true">16.</strong> Glossary of Technical Terms</a></li><li class="chapter-item expanded affix "><li class="part-title">For Developers</li><li class="chapter-item expanded "><a href="../DEVELOPER_README.html"><strong aria-hidden="true">17.</strong> Developer Guide</a></li><li class="chapter-item expanded "><a href="../developers/faq.html"><strong aria-hidden="true">18.</strong> FAQ</a></li><li class="chapter-item expanded "><div><strong aria-hidden="true">19.</strong> Design Documents</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="../developers/designs/access_profiles_rework_2022.html"><strong aria-hidden="true">19.1.</strong> Access Profiles 2022</a></li><li class="chapter-item expanded "><a href="../developers/designs/access_profiles_and_security.html"><strong aria-hidden="true">19.2.</strong> Access Profiles Original</a></li><li class="chapter-item expanded "><a href="../developers/designs/rest_interface.html"><strong aria-hidden="true">19.3.</strong> REST Interface</a></li><li class="chapter-item expanded "><a href="../developers/designs/elevated_priv_mode.html"><strong aria-hidden="true">19.4.</strong> Elevated Priv Mode</a></li></ol></li><li class="chapter-item expanded "><a href="../developers/python.html"><strong aria-hidden="true">20.</strong> Python Module</a></li><li class="chapter-item expanded "><a href="../developers/radius.html"><strong aria-hidden="true">21.</strong> RADIUS Integration</a></li><li class="chapter-item expanded "><a href="../packaging.html"><strong aria-hidden="true">22.</strong> Packaging</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../packaging_debs.html"><strong aria-hidden="true">22.1.</strong> Debian/Ubuntu</a></li></ol></li></ol>
|
|
</div>
|
|
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
|
</nav>
|
|
|
|
<div id="page-wrapper" class="page-wrapper">
|
|
|
|
<div class="page">
|
|
<div id="menu-bar-hover-placeholder"></div>
|
|
<div id="menu-bar" class="menu-bar sticky bordered">
|
|
<div class="left-buttons">
|
|
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
|
<i class="fa fa-bars"></i>
|
|
</button>
|
|
<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">
|
|
<i class="fa fa-paint-brush"></i>
|
|
</button>
|
|
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
|
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
|
</ul>
|
|
<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">
|
|
<i class="fa fa-search"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<h1 class="menu-title">Kanidm Administration</h1>
|
|
|
|
<div class="right-buttons">
|
|
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
|
<i id="print-button" class="fa fa-print"></i>
|
|
</a>
|
|
<a href="https://github.com/kanidm/kanidm" title="Git repository" aria-label="Git repository">
|
|
<i id="git-repository-button" class="fa fa-github"></i>
|
|
</a>
|
|
<a href="https://github.com/kanidm/kanidm/edit/master/book/src/integrations/oauth2.md" title="Suggest an edit" aria-label="Suggest an edit">
|
|
<i id="git-edit-button" class="fa fa-edit"></i>
|
|
</a>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div id="search-wrapper" class="hidden">
|
|
<form id="searchbar-outer" class="searchbar-outer">
|
|
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
|
</form>
|
|
<div id="searchresults-outer" class="searchresults-outer hidden">
|
|
<div id="searchresults-header" class="searchresults-header"></div>
|
|
<ul id="searchresults">
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
|
<script>
|
|
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
|
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
|
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
|
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
|
});
|
|
</script>
|
|
|
|
<div id="content" class="content">
|
|
<main>
|
|
<h1 id="oauth2"><a class="header" href="#oauth2">OAuth2</a></h1>
|
|
<p>OAuth is a web authorisation protocol that allows "single sign on". It's key to note OAuth only
|
|
provides authorisation, as the protocol in its default forms do not provide identity or
|
|
authentication information. All that Oauth2 provides is information that an entity is authorised for
|
|
the requested resources.</p>
|
|
<p>OAuth can tie into extensions allowing an identity provider to reveal information about authorised
|
|
sessions. This extends OAuth from an authorisation only system to a system capable of identity and
|
|
authorisation. Two primary methods of this exist today: RFC7662 token introspection, and OpenID
|
|
connect.</p>
|
|
<h2 id="how-does-oauth2-work"><a class="header" href="#how-does-oauth2-work">How Does OAuth2 Work?</a></h2>
|
|
<p>A user wishes to access a service (resource, resource server). The resource server does not have an
|
|
active session for the client, so it redirects to the authorisation server (Kanidm) to determine if
|
|
the client should be allowed to proceed, and has the appropriate permissions (scopes) for the
|
|
requested resources.</p>
|
|
<p>The authorisation server checks the current session of the user and may present a login flow if
|
|
required. Given the identity of the user known to the authorisation sever, and the requested scopes,
|
|
the authorisation server makes a decision if it allows the authorisation to proceed. The user is
|
|
then prompted to consent to the authorisation from the authorisation server to the resource server
|
|
as some identity information may be revealed by granting this consent.</p>
|
|
<p>If successful and consent given, the user is redirected back to the resource server with an
|
|
authorisation code. The resource server then contacts the authorisation server directly with this
|
|
code and exchanges it for a valid token that may be provided to the user's browser.</p>
|
|
<p>The resource server may then optionally contact the token introspection endpoint of the
|
|
authorisation server about the provided OAuth token, which yields extra metadata about the identity
|
|
that holds the token from the authorisation. This metadata may include identity information, but
|
|
also may include extended metadata, sometimes referred to as "claims". Claims are information bound
|
|
to a token based on properties of the session that may allow the resource server to make extended
|
|
authorisation decisions without the need to contact the authorisation server to arbitrate.</p>
|
|
<p>It's important to note that OAuth2 at its core is an authorisation system which has layered
|
|
identity-providing elements on top.</p>
|
|
<h3 id="resource-server"><a class="header" href="#resource-server">Resource Server</a></h3>
|
|
<p>This is the server that a user wants to access. Common examples could be Nextcloud, a wiki, or
|
|
something else. This is the system that "needs protecting" and wants to delegate authorisation
|
|
decisions to Kanidm.</p>
|
|
<p>It's important for you to know <em>how</em> your resource server supports OAuth2. For example, does it
|
|
support RFC 7662 token introspection or does it rely on OpenID connect for identity information?
|
|
Does the resource server support PKCE S256?</p>
|
|
<p>In general Kanidm requires that your resource server supports:</p>
|
|
<ul>
|
|
<li>HTTP basic authentication to the authorisation server</li>
|
|
<li>PKCE S256 code verification to prevent certain token attack classes</li>
|
|
<li>OIDC only - JWT ES256 for token signatures</li>
|
|
</ul>
|
|
<p>Kanidm will expose its OAuth2 APIs at the following URLs:</p>
|
|
<ul>
|
|
<li>user auth url: <code>https://idm.example.com/ui/oauth2</code></li>
|
|
<li>api auth url: <code>https://idm.example.com/oauth2/authorise</code></li>
|
|
<li>token url: <code>https://idm.example.com/oauth2/token</code></li>
|
|
<li>rfc7662 token introspection url: <code>https://idm.example.com/oauth2/token/introspect</code></li>
|
|
<li>rfc7009 token revoke url: <code>https://idm.example.com/oauth2/token/revoke</code></li>
|
|
</ul>
|
|
<p>OpenID Connect discovery - you need to substitute your OAuth2 client id in the following urls:</p>
|
|
<ul>
|
|
<li>OpenID connect issuer uri: <code>https://idm.example.com/oauth2/openid/:client\_id:/</code></li>
|
|
<li>OpenID connect discovery:
|
|
<code>https://idm.example.com/oauth2/openid/:client\_id:/.well-known/openid-configuration</code></li>
|
|
</ul>
|
|
<p>For manual OpenID configuration:</p>
|
|
<ul>
|
|
<li>OpenID connect userinfo: <code>https://idm.example.com/oauth2/openid/:client\_id:/userinfo</code></li>
|
|
<li>token signing public key: <code>https://idm.example.com/oauth2/openid/:client\_id:/public\_key.jwk</code></li>
|
|
</ul>
|
|
<h3 id="scope-relationships"><a class="header" href="#scope-relationships">Scope Relationships</a></h3>
|
|
<p>For an authorisation to proceed, the resource server will request a list of scopes, which are unique
|
|
to that resource server. For example, when a user wishes to login to the admin panel of the resource
|
|
server, it may request the "admin" scope from Kanidm for authorisation. But when a user wants to
|
|
login, it may only request "access" as a scope from Kanidm.</p>
|
|
<p>As each resource server may have its own scopes and understanding of these, Kanidm isolates scopes
|
|
to each resource server connected to Kanidm. Kanidm has two methods of granting scopes to accounts
|
|
(users).</p>
|
|
<p>The first is scope mappings. These provide a set of scopes if a user is a member of a specific group
|
|
within Kanidm. This allows you to create a relationship between the scopes of a resource server, and
|
|
the groups/roles in Kanidm which can be specific to that resource server.</p>
|
|
<p>For an authorisation to proceed, all scopes requested by the resource server must be available in
|
|
the final scope set that is granted to the account.</p>
|
|
<p>The second is supplemental scope mappings. These function the same as scope maps where membership of
|
|
a group provides a set of scopes to the account. However these scopes are NOT consulted during
|
|
authorisation decisions made by Kanidm. These scopes exists to allow optional properties to be
|
|
provided (such as personal information about a subset of accounts to be revealed) or so that the
|
|
resource server may make it's own authorisation decisions based on the provided scopes.</p>
|
|
<p>This use of scopes is the primary means to control who can access what resources. These access
|
|
decisions can take place either on Kanidm or the resource server.</p>
|
|
<p>For example, if you have a resource server that always requests a scope of "read", then users with
|
|
scope maps that supply the read scope will be allowed by Kanidm to proceed to the resource server.
|
|
Kanidm can then provide the supplementary scopes into provided tokens, so that the resource server
|
|
can use these to choose if it wishes to display UI elements. If a user has a supplemental "admin"
|
|
scope, then that user may be able to access an administration panel of the resource server. In this
|
|
way Kanidm is still providing the authorisation information, but the control is then exercised by
|
|
the resource server.</p>
|
|
<h2 id="configuration"><a class="header" href="#configuration">Configuration</a></h2>
|
|
<h3 id="create-the-kanidm-configuration"><a class="header" href="#create-the-kanidm-configuration">Create the Kanidm Configuration</a></h3>
|
|
<p>After you have understood your resource server requirements you first need to configure Kanidm. By
|
|
default members of "system_admins" or "idm_hp_oauth2_manage_priv" are able to create or manage
|
|
OAuth2 resource server integrations.</p>
|
|
<p>You can create a new resource server with:</p>
|
|
<pre><code class="language-bash">kanidm system oauth2 create <name> <displayname> <origin>
|
|
kanidm system oauth2 create nextcloud "Nextcloud Production" https://nextcloud.example.com
|
|
</code></pre>
|
|
<p>You can create a scope map with:</p>
|
|
<pre><code class="language-bash">kanidm system oauth2 update-scope-map <name> <kanidm_group_name> [scopes]...
|
|
kanidm system oauth2 update-scope-map nextcloud nextcloud_admins admin
|
|
</code></pre>
|
|
<!-- deno-fmt-ignore-start -->
|
|
<table>
|
|
<tr>
|
|
<td rowspan=2><img src="../images/kani-warning.png" alt="Kani Warning" /></td>
|
|
<td><strong>WARNING</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>If you are creating an OpenID Connect (OIDC) resource server you <b>MUST</b> provide a scope map named <code>openid</code>. Without this, OpenID clients <b>WILL NOT WORK</b>!</td>
|
|
</tr>
|
|
</table>
|
|
<!-- deno-fmt-ignore-end -->
|
|
<blockquote>
|
|
<p><strong>HINT</strong> OpenID connect allows a number of scopes that affect the content of the resulting
|
|
authorisation token. If one of the following scopes are requested by the OpenID client, then the
|
|
associated claims may be added to the authorisation token. It is not guaranteed that all of the
|
|
associated claims will be added.</p>
|
|
<ul>
|
|
<li>profile - (name, family_name, given_name, middle_name, nickname, preferred_username,
|
|
profile, picture, website, gender, birthdate, zoneinfo, locale, and updated_at)</li>
|
|
<li>email - (email, email_verified)</li>
|
|
<li>address - (address)</li>
|
|
<li>phone - (phone_number, phone_number_verified)</li>
|
|
</ul>
|
|
</blockquote>
|
|
<p>You can create a supplemental scope map with:</p>
|
|
<pre><code class="language-bash">kanidm system oauth2 update-sup-scope-map <name> <kanidm_group_name> [scopes]...
|
|
kanidm system oauth2 update-sup-scope-map nextcloud nextcloud_admins admin
|
|
</code></pre>
|
|
<p>Once created you can view the details of the resource server.</p>
|
|
<pre><code class="language-bash">kanidm system oauth2 get nextcloud
|
|
---
|
|
class: oauth2_resource_server
|
|
class: oauth2_resource_server_basic
|
|
class: object
|
|
displayname: Nextcloud Production
|
|
oauth2_rs_basic_secret: hidden
|
|
oauth2_rs_name: nextcloud
|
|
oauth2_rs_origin: https://nextcloud.example.com
|
|
oauth2_rs_token_key: hidden
|
|
</code></pre>
|
|
<p>You can see "oauth2_rs_basic_secret" with:</p>
|
|
<pre><code class="language-bash">kanidm system oauth2 show-basic-secret nextcloud
|
|
---
|
|
<secret>
|
|
</code></pre>
|
|
<h3 id="configure-the-resource-server"><a class="header" href="#configure-the-resource-server">Configure the Resource Server</a></h3>
|
|
<p>On your resource server, you should configure the client ID as the "oauth2_rs_name" from Kanidm,
|
|
and the password to be the value shown in "oauth2_rs_basic_secret". Ensure that the code
|
|
challenge/verification method is set to S256.</p>
|
|
<p>You should now be able to test authorisation.</p>
|
|
<h2 id="resetting-resource-server-security-material"><a class="header" href="#resetting-resource-server-security-material">Resetting Resource Server Security Material</a></h2>
|
|
<p>In the case of disclosure of the basic secret, or some other security event where you may wish to
|
|
invalidate a resource servers active sessions/tokens, you can reset the secret material of the
|
|
server with:</p>
|
|
<pre><code class="language-bash">kanidm system oauth2 reset-secrets
|
|
</code></pre>
|
|
<p>Each resource server has unique signing keys and access secrets, so this is limited to each resource
|
|
server.</p>
|
|
<h2 id="extended-options-for-legacy-clients"><a class="header" href="#extended-options-for-legacy-clients">Extended Options for Legacy Clients</a></h2>
|
|
<p>Not all resource servers support modern standards like PKCE or ECDSA. In these situations it may be
|
|
necessary to disable these on a per-resource server basis. Disabling these on one resource server
|
|
will not affect others.</p>
|
|
<!-- deno-fmt-ignore-start -->
|
|
<table>
|
|
<tr>
|
|
<td rowspan=2><img src="../images/kani-warning.png" alt="Kani Warning" /></td>
|
|
<td><strong>WARNING text=Changing these settings MAY have serious consequences on the security of your resource server. You should avoid changing these if at all possible!</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
</tr>
|
|
</table>
|
|
<!-- deno-fmt-ignore-end -->
|
|
<p>To disable PKCE for a resource server:</p>
|
|
<pre><code class="language-bash">kanidm system oauth2 warning-insecure-client-disable-pkce <resource server name>
|
|
</code></pre>
|
|
<p>To enable legacy cryptograhy (RSA PKCS1-5 SHA256):</p>
|
|
<pre><code class="language-bash">kanidm system oauth2 warning-enable-legacy-crypto <resource server name>
|
|
</code></pre>
|
|
<h2 id="example-integrations"><a class="header" href="#example-integrations">Example Integrations</a></h2>
|
|
<h3 id="apache-mod_auth_openidc"><a class="header" href="#apache-mod_auth_openidc">Apache mod_auth_openidc</a></h3>
|
|
<p>Add the following to a <code>mod_auth_openidc.conf</code>. It should be included in a <code>mods_enabled</code> folder or
|
|
with an appropriate include.</p>
|
|
<pre><code class="language-conf">OIDCRedirectURI /protected/redirect_uri
|
|
OIDCCryptoPassphrase <random password here>
|
|
OIDCProviderMetadataURL https://kanidm.example.com/oauth2/openid/<resource server name>/.well-known/openid-configuration
|
|
OIDCScope "openid"
|
|
OIDCUserInfoTokenMethod authz_header
|
|
OIDCClientID <resource server name>
|
|
OIDCClientSecret <resource server password>
|
|
OIDCPKCEMethod S256
|
|
OIDCCookieSameSite On
|
|
# Set the `REMOTE_USER` field to the `preferred_username` instead of the UUID.
|
|
# Remember that the username can change, but this can help with systems like Nagios which use this as a display name.
|
|
# OIDCRemoteUserClaim preferred_username
|
|
</code></pre>
|
|
<p>Other scopes can be added as required to the <code>OIDCScope</code> line, eg:
|
|
<code>OIDCScope "openid scope2 scope3"</code></p>
|
|
<p>In the virtual host, to protect a location:</p>
|
|
<pre><code class="language-apache"><Location />
|
|
AuthType openid-connect
|
|
Require valid-user
|
|
</Location>
|
|
</code></pre>
|
|
<h3 id="nextcloud"><a class="header" href="#nextcloud">Nextcloud</a></h3>
|
|
<p>Install the module <a href="https://apps.nextcloud.com/apps/user_oidc">from the nextcloud market place</a> - it
|
|
can also be found in the Apps section of your deployment as "OpenID Connect user backend".</p>
|
|
<p>In Nextcloud's config.php you need to allow connection to remote servers:</p>
|
|
<pre><code class="language-php">'allow_local_remote_servers' => true,
|
|
</code></pre>
|
|
<p>You may optionally choose to add:</p>
|
|
<pre><code class="language-php">'allow_user_to_change_display_name' => false,
|
|
'lost_password_link' => 'disabled',
|
|
</code></pre>
|
|
<p>If you forget this, you may see the following error in logs:</p>
|
|
<pre><code class="language-bash">Host 172.24.11.129 was not connected to because it violates local access rules
|
|
</code></pre>
|
|
<p>This module does not support PKCE or ES256. You will need to run:</p>
|
|
<pre><code class="language-bash">kanidm system oauth2 warning_insecure_client_disable_pkce <resource server name>
|
|
kanidm system oauth2 warning_enable_legacy_crypto <resource server name>
|
|
</code></pre>
|
|
<p>In the settings menu, configure the discovery URL and client ID and secret.</p>
|
|
<p>You can choose to disable other login methods with:</p>
|
|
<pre><code class="language-bash">php occ config:app:set --value=0 user_oidc allow_multiple_user_backends
|
|
</code></pre>
|
|
<p>You can login directly by appending <code>?direct=1</code> to your login page. You can re-enable other backends
|
|
by setting the value to <code>1</code></p>
|
|
<h3 id="velociraptor"><a class="header" href="#velociraptor">Velociraptor</a></h3>
|
|
<p>Velociraptor supports OIDC. To configure it select "Authenticate with SSO" then "OIDC" during the
|
|
interactive configuration generator. Alternately, you can set the following keys in
|
|
server.config.yaml:</p>
|
|
<pre><code class="language-yaml">GUI:
|
|
authenticator:
|
|
type: OIDC
|
|
oidc_issuer: https://idm.example.com/oauth2/openid/:client\_id:/
|
|
oauth_client_id: <resource server name/>
|
|
oauth_client_secret: <resource server secret>
|
|
</code></pre>
|
|
<p>Velociraptor does not support PKCE. You will need to run the following:</p>
|
|
<pre><code class="language-bash">kanidm system oauth2 warning_insecure_client_disable_pkce <resource server name>
|
|
</code></pre>
|
|
<p>Initial users are mapped via their email in the Velociraptor server.config.yaml config:</p>
|
|
<pre><code class="language-yaml">GUI:
|
|
initial_users:
|
|
- name: <email address>
|
|
</code></pre>
|
|
<p>Accounts require the <code>openid</code> and <code>email</code> scopes to be authenticated. It is recommended you limit
|
|
these to a group with a scope map due to Velociraptors high impact.</p>
|
|
<pre><code class="language-bash"># kanidm group create velociraptor_users
|
|
# kanidm group add_members velociraptor_users ...
|
|
kanidm system oauth2 create_scope_map <resource server name> velociraptor_users openid email
|
|
</code></pre>
|
|
<h3 id="vouch-proxy"><a class="header" href="#vouch-proxy">Vouch Proxy</a></h3>
|
|
<blockquote>
|
|
<p><strong>WARNING</strong> Vouch proxy requires a unique identifier but does not use the proper scope, "sub". It
|
|
uses the fields "username" or "email" as primary identifiers instead. As a result, this can cause
|
|
user or deployment issues, at worst security bypasses. You should avoid Vouch Proxy if possible
|
|
due to these issues.</p>
|
|
<ul>
|
|
<li><a href="https://github.com/vouch/vouch-proxy/issues/309">https://github.com/vouch/vouch-proxy/issues/309</a></li>
|
|
<li><a href="https://github.com/vouch/vouch-proxy/issues/310">https://github.com/vouch/vouch-proxy/issues/310</a></li>
|
|
</ul>
|
|
</blockquote>
|
|
<p>Note: <strong>You need to run at least the version 0.37.0</strong></p>
|
|
<p>Vouch Proxy supports multiple OAuth and OIDC login providers. To configure it you need to pass:</p>
|
|
<pre><code class="language-yaml">oauth:
|
|
auth_url: https://idm.wherekanidmruns.com/ui/oauth2
|
|
callback_url: https://login.wherevouchproxyruns.com/auth
|
|
client_id: <oauth2_rs_name> # Found in kanidm system oauth2 get XXXX (should be the same as XXXX)
|
|
client_secret: <oauth2_rs_basic_secret> # Found in kanidm system oauth2 get XXXX
|
|
code_challenge_method: S256
|
|
provider: oidc
|
|
scopes:
|
|
- email # Required due to vouch proxy reliance on mail as a primary identifier
|
|
token_url: https://idm.wherekanidmruns.com/oauth2/token
|
|
user_info_url: https://idm.wherekanidmruns.com/oauth2/openid/<oauth2_rs_name>/userinfo
|
|
</code></pre>
|
|
<p>The <code>email</code> scope needs to be passed and thus the mail attribute needs to exist on the account:</p>
|
|
<pre><code class="language-bash">kanidm person update <ID> --mail "YYYY@somedomain.com" --name idm_admin
|
|
</code></pre>
|
|
|
|
</main>
|
|
|
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
|
<!-- Mobile navigation buttons -->
|
|
<a rel="prev" href="../ssh_key_dist.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|
<i class="fa fa-angle-left"></i>
|
|
</a>
|
|
|
|
<a rel="next" href="../integrations/ldap.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
|
|
<div style="clear: both"></div>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
|
|
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
|
<a rel="prev" href="../ssh_key_dist.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|
<i class="fa fa-angle-left"></i>
|
|
</a>
|
|
|
|
<a rel="next" href="../integrations/ldap.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
</nav>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
window.playground_copyable = true;
|
|
</script>
|
|
|
|
|
|
<script src="../elasticlunr.min.js"></script>
|
|
<script src="../mark.min.js"></script>
|
|
<script src="../searcher.js"></script>
|
|
|
|
<script src="../clipboard.min.js"></script>
|
|
<script src="../highlight.js"></script>
|
|
<script src="../book.js"></script>
|
|
|
|
<!-- Custom JS scripts -->
|
|
|
|
|
|
</div>
|
|
</body>
|
|
</html>
|