Add introduction section to federation docs
Add an introduction to the federation documentation discussing background information on identity federation and how it is implemented in keystone. This repurposes some of the content in this blog post[1] of which I am the author. [1] http://www.gazlene.net/demystifying-keystone-federation.html Partial-bug: #1793374 Change-Id: I5f3a5e70c7b868762880930ea6277691f44c046a
This commit is contained in:
parent
ecfe59b1a9
commit
4a141fea51
@ -4,6 +4,7 @@
|
||||
openstackdocstheme>=1.18.1 # Apache-2.0
|
||||
sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD
|
||||
sphinxcontrib-apidoc>=0.2.0 # BSD
|
||||
sphinxcontrib-seqdiag>=0.8.4 # BSD
|
||||
reno>=2.5.0 # Apache-2.0
|
||||
os-api-ref>=1.4.0 # Apache-2.0
|
||||
python-ldap>=3.0.0 # PSF
|
||||
|
@ -14,14 +14,6 @@
|
||||
Configuring Keystone for Federation
|
||||
===================================
|
||||
|
||||
-----------
|
||||
Definitions
|
||||
-----------
|
||||
* `Service Provider (SP)`: provides a service to an end-user.
|
||||
* `Identity Provider (IdP)`: service that stores information about users and
|
||||
groups.
|
||||
* `SAML assertion`: contains information about a user as provided by an IdP.
|
||||
|
||||
-----------------------------------
|
||||
Keystone as a Service Provider (SP)
|
||||
-----------------------------------
|
||||
|
@ -4,6 +4,7 @@ Federated Identity
|
||||
|
||||
Keystone's one-stop-shop for all federated identity documentation.
|
||||
|
||||
.. include:: introduction.rst
|
||||
.. include:: configure_federation.rst
|
||||
.. include:: mapping_combinations.rst
|
||||
.. include:: openidc.rst
|
||||
|
424
doc/source/admin/federation/introduction.rst
Normal file
424
doc/source/admin/federation/introduction.rst
Normal file
@ -0,0 +1,424 @@
|
||||
..
|
||||
Copyright 2018 SUSE Linux GmbH
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Introduction to Keystone Federation
|
||||
===================================
|
||||
|
||||
----------------------------
|
||||
What is keystone federation?
|
||||
----------------------------
|
||||
|
||||
Identity federation is the ability to share identity information across multiple
|
||||
identity management systems. In keystone, this is implemented as an
|
||||
authentication method that allows users to authenticate directly with another
|
||||
identity source and then provides keystone with a set of user attributes. This
|
||||
is useful if your organization already has a primary identity source since it
|
||||
means users don't need a separate set of credentials for the cloud. It is also
|
||||
useful for connecting multiple clouds together, as we can use a keystone in
|
||||
another cloud as an identity source. Using `LDAP as an identity backend`_ is
|
||||
another way for keystone to obtain identity information from an external source,
|
||||
but it requires keystone to handle passwords directly rather than offloading
|
||||
authentication to the external source.
|
||||
|
||||
Keystone supports two configuration models for federated identity. The most
|
||||
common configuration is with `keystone as a Service Provider (SP)`_, using an
|
||||
external Identity Provider, such as a Keycloak or Google, as the identity source
|
||||
and authentication method. The second type of configuration is "`Keystone to
|
||||
Keystone`_", where two keystones are linked with one acting as the identity
|
||||
source.
|
||||
|
||||
This document discusses identity federation involving a secondary identity
|
||||
management that acts as the source of truth concerning the users it contains,
|
||||
specifically covering the SAML2.0 and OpenID Connect protocols, although
|
||||
keystone can work with other protocols. A similar concept is `external
|
||||
authentication`_ whereby keystone is still the source of truth about its users
|
||||
but authentication is handled externally. Yet another closely related topic is
|
||||
`tokenless authentication`_ which uses some of the same constructs as described
|
||||
here but allows services to validate users without using keystone tokens.
|
||||
|
||||
.. _LDAP as an identity backend: ../../admin/identity-integrate-with-ldap.html
|
||||
.. _keystone as a Service Provider (SP): configure_federation.html#keystone-as-a-service-provider-sp
|
||||
.. _Keystone to Keystone: configure_federation.html#keystone-as-an-identity-provider-idp
|
||||
.. _external authentication: ../external-authentication.html
|
||||
.. _tokenless authentication: ../configure_tokenless_x509.html
|
||||
|
||||
--------
|
||||
Glossary
|
||||
--------
|
||||
|
||||
**Service Provider (SP)**
|
||||
A Service Provider is the service providing the resource an end-user is
|
||||
requesting. In our case, this is keystone, which provides keystone tokens that
|
||||
we use on other OpenStack services. We do NOT call the other OpenStack
|
||||
services "service providers". The specific service we care about in this
|
||||
context is the token service, so that is our Service Provider.
|
||||
|
||||
**Identity Provider (IdP)**
|
||||
An Identity Provider is the service that accepts credentials, validates
|
||||
them, and generates a yay/nay response. It returns this response along with
|
||||
some other attributes about the user, such as their username, their display
|
||||
name, and whatever other details it stores and you've configured your Service
|
||||
Provider to accept.
|
||||
|
||||
**Entity ID or Remote ID**
|
||||
An Entity ID or a Remote ID are both names for a unique identifier string for
|
||||
either a Service Provider or an Identity Provider. It usually takes the form
|
||||
of a URN, but the URN does not need to be a resolvable URL. The only
|
||||
requirement is that it uniquely identifies the IdP to the SP, or the SP to the
|
||||
IdP.
|
||||
|
||||
**SAML2.0**
|
||||
`SAML2.0`_ is an XML-based federation protocol. It is commonly used in
|
||||
internal-facing organizations, such as a university or business in which IT
|
||||
services are provided to members of the organization.
|
||||
|
||||
**OpenID Connect (OpenIDC)**
|
||||
`OpenID Connect`_ is a JSON-based federation protocol built on OAuth 2.0. It's
|
||||
used more often by public-facing services like Google.
|
||||
|
||||
**Assertion**
|
||||
An assertion is a formatted statement from the Identity Provider that asserts
|
||||
that a user is authenticated and provides some attributes about the user. The
|
||||
Identity Provider always signs the assertion and typically encrypts it as
|
||||
well.
|
||||
|
||||
**Single Sign-On (SSO)**
|
||||
`Single Sign-On`_ is a mechanism related to identity federation whereby a user
|
||||
may log in to their identity management system and be granted a token or
|
||||
ticket that allows them access to multiple Service Providers.
|
||||
|
||||
.. _SAML2.0: http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html
|
||||
.. _OpenID Connect: https://openid.net/connect/
|
||||
.. _Single Sign-On: https://en.wikipedia.org/wiki/Single_sign-on
|
||||
|
||||
--------------------
|
||||
Authentication Flows
|
||||
--------------------
|
||||
|
||||
Understanding the flow of information as a user moves through the authentication
|
||||
process is key to being able to debug later on.
|
||||
|
||||
Normal keystone
|
||||
---------------
|
||||
|
||||
.. seqdiag::
|
||||
:name: normal-keystone
|
||||
:alt: Diagram of keystone's normal auth flow, in which a user agent
|
||||
authenticates and authorizes themself with keystone and obtains a
|
||||
scoped token to pass to an OpenStack service.
|
||||
|
||||
seqdiag {
|
||||
default_fontsize = 13;
|
||||
useragent [label = "User Agent"]; keystone [label = "Keystone"]; openstack [label = "OpenStack"];
|
||||
useragent -> keystone [label = "GET /v3/auth/tokens"];
|
||||
keystone -> keystone [label = "Authenticate"];
|
||||
keystone -> keystone [label = "Authorize"];
|
||||
useragent <- keystone [label = "Scoped token"];
|
||||
useragent -> openstack [label = "GET /v2.1/servers"];
|
||||
}
|
||||
|
||||
In a normal keystone flow, the user requests a scoped token directly from
|
||||
keystone. Keystone accepts their credentials and checks them against its local
|
||||
storage or against its LDAP backend. Then it checks the scope that the user is
|
||||
requesting, ensuring they have the correct role assignments, and produces a
|
||||
scoped token. The user can use the scoped token to do something else in
|
||||
OpenStack, like request servers, but everything that happens after the token is
|
||||
produced is irrelevant to this discussion.
|
||||
|
||||
SAML2.0
|
||||
-------
|
||||
|
||||
SAML2.0 WebSSO
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
.. seqdiag::
|
||||
:name: saml2-websso
|
||||
:alt: Diagram of a standard WebSSO authentication flow.
|
||||
|
||||
seqdiag {
|
||||
edge_length = 325;
|
||||
default_fontsize = 13;
|
||||
useragent [label = "User Agent"]; sp [label = "Service Provider"]; idp [label = "Identity Provider"];
|
||||
useragent -> sp [label = "GET /secure"];
|
||||
useragent <- sp [label = "HTTP 302
|
||||
Location: https://idp/auth?
|
||||
SAMLRequest=req"];
|
||||
useragent -> idp [label = "GET /auth?SAMLRequest=req"];
|
||||
idp -> idp [label = "Authenticate"];
|
||||
useragent <- idp [label = "HTTP 200
|
||||
SAMLResponse in HTML form"];
|
||||
useragent -> sp [label = "POST /assertionconsumerservice"];
|
||||
sp -> sp [label = "Validate"];
|
||||
useragent <- sp [label = "HTTP 302; Location: /secure"];
|
||||
useragent -> sp [label = "GET /secure"];
|
||||
}
|
||||
|
||||
This diagram shows a standard `WebSSO`_ authentication flow, not one involving
|
||||
keystone. WebSSO is one of a few `SAML2.0 profiles`_. It is based on the idea that a
|
||||
web browser will be acting as an intermediary and so the flow involves concepts
|
||||
that a browser can understand and act on, like HTTP redirects and HTML forms.
|
||||
|
||||
First, the user uses their web browser to request some secure resource from the
|
||||
Service Provider. The Service Provider detects that the user isn't authenticated
|
||||
yet, so it generates a SAML Request which it base64 encodes, and then issues an
|
||||
HTTP redirect to the Identity Provider.
|
||||
|
||||
The browser follows the redirect and presents the SAML Request to the Identity
|
||||
Provider. The user is prompted to authenticate, probably by filling out a
|
||||
username and password in a login page. The Identity Provider responds with an
|
||||
HTTP success and generates a SAML Response with an HTML form.
|
||||
|
||||
The browser automatically POSTs the form back to the Service Provider, which
|
||||
validates the SAML Response. The Service Provider finally issues another
|
||||
redirect back to the original resource the user had requested.
|
||||
|
||||
.. _WebSSO: http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0-cd-02.html#5.1.Web%20Browser%20SSO%20Profile|outline
|
||||
.. _SAML2.0 profiles: http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0-cd-02.html#5.Major%20Profiles%20and%20Federation%20Use%20Cases|outline
|
||||
|
||||
SAML2.0 ECP
|
||||
~~~~~~~~~~~
|
||||
|
||||
.. seqdiag::
|
||||
:name: saml2-ecp
|
||||
:alt: Diagram of a standard ECP authentication flow.
|
||||
|
||||
seqdiag {
|
||||
default_fontsize = 13;
|
||||
useragent [label = "User Agent"]; sp [label = "Service Provider"]; idp [label = "Identity Provider"];
|
||||
useragent -> sp [label = "GET /secure"];
|
||||
useragent <- sp [label = "HTTP 200
|
||||
SAML Request"];
|
||||
useragent -> idp [label = "POST /auth
|
||||
SAML Request"];
|
||||
idp -> idp [label = "Authenticate"];
|
||||
useragent <- idp [label = "HTTP 200
|
||||
SAMLResponse in SOAP"];
|
||||
useragent -> sp [label = "POST /responseconsumer"];
|
||||
sp -> sp [label = "Validate"];
|
||||
useragent <- sp [label = "HTTP 200 /secure"];
|
||||
}
|
||||
|
||||
`ECP`_ is another SAML profile. Generally the flow is similar to the WebSSO
|
||||
flow, but it is designed for a client that natively understands SAML, for
|
||||
example the `keystoneauth`_ library (and therefore also the
|
||||
`python-openstackclient
|
||||
<https://docs.openstack.org/python-openstackclient/latest/>`__ CLI tool). ECP is
|
||||
slightly different from the browser-based flow and is not supported by all
|
||||
SAML2.0 IdPs, and so getting WebSSO working does not necessarily mean ECP is
|
||||
working correctly, or vice versa. ECP support must often be turned on explicitly
|
||||
in the Identity Provider.
|
||||
|
||||
.. _ECP: http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0-cd-02.html#5.2.ECP%20Profile|outline
|
||||
.. _keystoneauth: https://docs.openstack.org/keystoneauth/latest/
|
||||
|
||||
WebSSO with keystone and horizon
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
.. seqdiag::
|
||||
:name: saml2-keystone-horizon
|
||||
:alt: Diagram of the SAML2.0 WebSSO auth flow specific to horizon, keystone, and the
|
||||
HTTPD module acting as service provider.
|
||||
|
||||
seqdiag {
|
||||
default_fontsize = 13;
|
||||
useragent [label = "User Agent"]; horizon [label = "Horizon"]; httpd [label = "HTTPD", color = "lightgrey"]; keystone [label = "Keystone", color = "lightgrey"]; idp [label = "Identity Provider"];
|
||||
useragent -> horizon [label = "POST /auth/login"];
|
||||
useragent <- horizon [label = "HTTP 302
|
||||
Location:
|
||||
/v3/auth/OS-FEDERATION
|
||||
/websso/saml2"];
|
||||
useragent -> httpd [label = "GET /v3/auth/OS-FEDERATION/websso/saml2"];
|
||||
useragent <- httpd [label = "HTTP 302
|
||||
Location: https://idp/auth?SAMLRequest=req"];
|
||||
useragent -> idp [label = "GET /auth"];
|
||||
idp -> idp [label = "Authenticate"];
|
||||
useragent <- idp [label = "HTTP 200
|
||||
SAMLResponse in HTML form"];
|
||||
useragent -> httpd [label = "POST /assertionconsumerservice"];
|
||||
httpd -> httpd [label = "Validate"];
|
||||
useragent <- httpd [label = "HTTP 302
|
||||
Location: /v3/auth/OS-FEDERATION/websso/saml2"];
|
||||
useragent -> keystone [label = "GET /v3/auth/OS-FEDERATION/websso/saml2"];
|
||||
keystone -> keystone [label = "Issue token"];
|
||||
useragent <- keystone [label = "HTTP 200
|
||||
HTML form containing unscoped token"];
|
||||
useragent -> horizon [label = "POST /auth/websso"];
|
||||
useragent <- horizon [label = "successful login"];
|
||||
}
|
||||
|
||||
Keystone is not a web front-end, which means horizon needs to handle some parts
|
||||
of being a Service Provider to implement WebSSO.
|
||||
|
||||
In the diagram above, horizon is added, and keystone and HTTPD are split out
|
||||
from each other to distinguish which parts each are responsible for, though
|
||||
typically both together are referred to as the Service Provider.
|
||||
|
||||
In this model, the user requests to log in to horizon by selecting a federated
|
||||
authentication method from a dropdown menu. Horizon automatically generates a
|
||||
keystone URL based on the Identity Provider and protocol selected and redirects
|
||||
the browser to keystone. That location is equivalent to the /secure resource in
|
||||
the `SAML2.0 WebSSO`_ diagram. The browser follows the redirect, and the HTTPD
|
||||
module detects that the user isn't logged in yet and issues another redirect to
|
||||
the Identity Provider with a SAML Request. At this point, the flow is the same
|
||||
as in the normal WebSSO model. The user logs into the Identity Provider, a SAML
|
||||
Response is POSTed back to the Service Provider, where the HTTPD module
|
||||
validates the response and issues a redirect back to the location that horizon
|
||||
had originally requested, which is a special federation auth endpoint. At this
|
||||
point keystone is able to grant an unscoped token, which it hands off as another
|
||||
HTML form. The browser will POST that back to horizon, which triggers the normal
|
||||
login process, picking a project to scope to and getting a scoped token from
|
||||
keystone.
|
||||
|
||||
Note that horizon is acting as a middleman, since it knows the endpoint of the
|
||||
secure resource it requests from keystone.
|
||||
|
||||
Keystone to Keystone
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. seqdiag::
|
||||
:name: keystone-to-keystone
|
||||
:alt: Diagram of the IdP-initiated auth flow in a keystone-to-keystone model.
|
||||
|
||||
seqdiag {
|
||||
edge_length = 240;
|
||||
default_fontsize = 13;
|
||||
useragent [label = "User Agent"]; sp [label = "Service Provider"]; idp [label = "Identity Provider"];
|
||||
useragent -> idp [label = "POST /v3/auth/tokens"];
|
||||
idp -> idp [label = "Authenticate"];
|
||||
useragent <- idp [label = "HTTP 201
|
||||
X-Subject-Token: token"];
|
||||
useragent -> idp [label = "POST /v3/auth/OS-FEDERATION/saml2/ecp"];
|
||||
useragent <- idp [label = "HTTP 201
|
||||
SAMLResponse in SOAP envelope"];
|
||||
useragent -> sp [label = "POST /PAOS-url"];
|
||||
sp -> sp [label = "Validate"];
|
||||
useragent <- sp [label = "HTTP 201
|
||||
X-Subject-Token: unscoped token"];
|
||||
useragent -> sp [label = "POST /v3/auth/tokens
|
||||
(request scoped token)"];
|
||||
}
|
||||
|
||||
When keystone is used as an Identity Provider in a Keystone to Keystone
|
||||
configuration, the auth flow is nonstandard. It is similar to an `IdP-initiated
|
||||
auth flow`_. In this case, the user goes directly to the Identity Provider first
|
||||
before requesting any resource from the Service Provider. The user will get a
|
||||
token from keystone, then use that to request a SAML Response via ECP. When it
|
||||
gets that response back, it POSTs that to the Service Provider, which will grant
|
||||
a token for it.
|
||||
|
||||
Notice that the Service Provider has to accept data from the Identity Provider
|
||||
and therefore needs to have a way of trusting it. The Identity Provider, on the
|
||||
other hand, never has to accept data from the Service Provider. There is no back
|
||||
and forth, the user simply completes the auth process on one side and presents
|
||||
the result to the other side.
|
||||
|
||||
.. _IdP-initiated auth flow: http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0-cd-02.html#5.1.4.IdP-Initiated%20SSO:%20%20POST%20Binding|outline
|
||||
|
||||
OpenID Connect
|
||||
--------------
|
||||
|
||||
OpenID Connect Authentication Flow
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. seqdiag::
|
||||
:name: openidc
|
||||
:alt: Diagram of a standard OpenID Connect authentication flow
|
||||
:align: left
|
||||
|
||||
seqdiag {
|
||||
edge_length = 330;
|
||||
default_fontsize = 13;
|
||||
useragent [label = "User Agent"]; sp [label = "Service Provider"]; idp [label = "Identity Provider"];
|
||||
useragent -> sp [label = "GET /secure"];
|
||||
useragent <- sp [label = "HTTP 302
|
||||
Location: https://idp/auth?
|
||||
client_id=XXX&redirect_uri=https://sp/secure"];
|
||||
useragent -> idp [label = "GET /auth?client_id=XXX&redirect_uri=https://sp/secure"];
|
||||
idp -> idp [label = "Authenticate"];
|
||||
useragent <- idp [label = "HTTP 302
|
||||
Location: https://sp/auth?code=XXX"];
|
||||
useragent -> sp [label = "GET /auth?code=XXX"];
|
||||
sp -> idp [label = "POST https://idp/token
|
||||
code=XXX&redirect_uri=https://sp/secure"];
|
||||
sp <- idp [label = "HTTP 200
|
||||
{\"access_code\": \"XXX\",
|
||||
\"id_token\": \"XXX\"}"];
|
||||
useragent <- sp [label = "HTTP 302; Location: /secure"];
|
||||
useragent -> sp [label = "GET /secure"];
|
||||
}
|
||||
|
||||
OpenID Connect is different from any SAML2.0 flow because the negotiation is not
|
||||
handled entirely through the client. The Service Provider must make a request
|
||||
directly to the Identity Provider, which means this flow would not be
|
||||
appropriate if the Service Provider and Identity Provider are in segregated
|
||||
networks.
|
||||
|
||||
When the user requests a secure resource from the Service Provider, they are
|
||||
redirected to the Identity Provider to log in. The Identity Provider then
|
||||
redirects the user back to the Service Provider using a known redirect URI and
|
||||
providing an authorization code. The Service Provider must then make a
|
||||
back-channel request directly to the Identity Provider using the provided code,
|
||||
and exchange it for an ID token.
|
||||
|
||||
OpenID Connect with keystone and horizon
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. seqdiag::
|
||||
:name: oidc-keystone-horizon
|
||||
:alt: Diagram of the OpenID Connect WebSSO auth flow specific to horizon,
|
||||
keystone, and the HTTPD module acting as service provider.
|
||||
|
||||
seqdiag {
|
||||
edge_length = 200
|
||||
default_fontsize = 13;
|
||||
useragent [label = "User Agent"]; horizon [label = "Horizon"]; httpd [label = "HTTPD", color = "lightgrey"]; keystone [label = "Keystone", color = "lightgrey"]; idp [label = "Identity Provider"];
|
||||
useragent -> horizon [label = "POST /auth/login"];
|
||||
useragent <- horizon [label = "HTTP 302
|
||||
Location:
|
||||
/v3/auth/OS-FEDERATION
|
||||
/websso/saml2"];
|
||||
useragent -> httpd [label = "GET /v3/auth/OS-FEDERATION/websso/saml2"];
|
||||
useragent <- httpd [label = "HTTP 302
|
||||
Location:
|
||||
https://idp/auth?
|
||||
client_id=XXX&
|
||||
redirect_uri=https://sp/v3/auth/OS-FEDERATION/websso"];
|
||||
useragent -> idp [label = "GET /auth?client_id=XXX&
|
||||
redirect_uri=https://sp/v3/auth/OS-FEDERATION/websso"];
|
||||
idp -> idp [label = "Authenticate"];
|
||||
useragent <- idp [label = "HTTP 302
|
||||
Location: https://sp/v3/auth/OS-FEDERATION/websso"];
|
||||
useragent -> httpd [label = "GET /v3/auth/OS-FEDERATION/websso"];
|
||||
httpd -> idp [label = "POST https://idp/token
|
||||
code=XXX&
|
||||
redirect_uri=https://sp/v3/auth/OS-FEDERATION/websso"];
|
||||
httpd <- idp [label = "HTTP 200
|
||||
{\"access_code\": \"XXX\",
|
||||
\"id_token\": \"XXX\"}"];
|
||||
useragent <- httpd [label = "HTTP 302
|
||||
Location: /v3/auth/OS-FEDERATION/websso/mapped"];
|
||||
useragent -> keystone [label = "GET /v3/auth/OS-FEDERATION/websso/mapped"];
|
||||
keystone -> keystone [label = "Issue token"];
|
||||
useragent <- keystone [label = "HTTP 200
|
||||
HTML form containing unscoped token"];
|
||||
useragent -> horizon [label = "POST /auth/websso"];
|
||||
useragent <- horizon [label = "successful login"];
|
||||
}
|
||||
|
||||
From horizon and keystone's point of view, the authentication flow is the same
|
||||
for OpenID Connect as it is for SAML2.0. It is only the HTTPD OpenIDC module
|
||||
that must handle the flow in accordance with the spec.
|
@ -54,6 +54,7 @@ extensions = ['sphinx.ext.coverage',
|
||||
'oslo_policy.sphinxext',
|
||||
'ext.support_matrix',
|
||||
'sphinxcontrib.apidoc',
|
||||
'sphinxcontrib.seqdiag',
|
||||
]
|
||||
|
||||
# sphinxcontrib.apidoc options
|
||||
@ -65,6 +66,10 @@ apidoc_excluded_paths = [
|
||||
'test']
|
||||
apidoc_separate_modules = True
|
||||
|
||||
# sphinxcontrib.seqdiag options
|
||||
seqdiag_antialias = True
|
||||
seqdiag_html_image_format = 'SVG'
|
||||
|
||||
config_generator_config_file = '../../config-generator/keystone.conf'
|
||||
sample_config_basename = '_static/keystone'
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user