Blame ECP.rst

Packit Service d6b4c9
Guide to using ECP
Packit Service d6b4c9
==================
Packit Service d6b4c9
Packit Service d6b4c9
Introduction
Packit Service d6b4c9
------------
Packit Service d6b4c9
Packit Service d6b4c9
The **Enhanced Client or Proxy** (ECP) profile of SAML2
Packit Service d6b4c9
Packit Service d6b4c9
The Enhanced Client or Proxy (ECP) Profile supports several SSO use
Packit Service d6b4c9
cases, in particular:
Packit Service d6b4c9
Packit Service d6b4c9
  * Clients with capabilities beyond those of a browser, allowing them
Packit Service d6b4c9
    to more actively participate in IdP discovery and message flow.
Packit Service d6b4c9
Packit Service d6b4c9
  * Using a proxy server, for example a WAP gateway in front of a mobile
Packit Service d6b4c9
    device which has limited functionality.
Packit Service d6b4c9
Packit Service d6b4c9
  * When other bindings are precluded (e.g. where the client does not
Packit Service d6b4c9
    support redirects, or when auto form post is not possible without
Packit Service d6b4c9
    Javascript, or when the artifact binding is ruled out because the
Packit Service d6b4c9
    identity provider and service provider cannot directly communicate.
Packit Service d6b4c9
Packit Service d6b4c9
An enhanced client or proxy (ECP) is a system entity that knows how to
Packit Service d6b4c9
contact an appropriate identity provider, possibly in a
Packit Service d6b4c9
context-dependent fashion, and also supports the Reverse SOAP (PAOS)
Packit Service d6b4c9
binding.
Packit Service d6b4c9
Packit Service d6b4c9
An example scenario enabled by ECP profile is as follows: A principal,
Packit Service d6b4c9
wielding an ECP, uses it to either access a resource at a service
Packit Service d6b4c9
provider, or access an identity provider such that the service
Packit Service d6b4c9
provider and desired resource are understood or implicit. The
Packit Service d6b4c9
principal authenticates (or has already authenticated) with the
Packit Service d6b4c9
identity provider [1]_, which then produces an authentication assertion
Packit Service d6b4c9
(possibly with input from the service provider). The service provider
Packit Service d6b4c9
then consumes the assertion and subsequently establishes a security
Packit Service d6b4c9
context for the principal. During this process, a name identifier
Packit Service d6b4c9
might also be established between the providers for the principal,
Packit Service d6b4c9
subject to the parameters of the interaction and the consent of the
Packit Service d6b4c9
principal.
Packit Service d6b4c9
Packit Service d6b4c9
SAML2 Profile for ECP (Section 4.2) defines these steps for an ECP
Packit Service d6b4c9
transaction:
Packit Service d6b4c9
Packit Service d6b4c9
  1. ECP issues HTTP Request to SP
Packit Service d6b4c9
  2. SP issues <AuthnRequest> to ECP using PAOS
Packit Service d6b4c9
  3. ECP determines IdP
Packit Service d6b4c9
  4. ECP conveys <AuthnRequest> to IdP using SOAP
Packit Service d6b4c9
  5. IdP identifies principal
Packit Service d6b4c9
  6. IdP issues <Response> to ECP, targeted at SP using SOAP
Packit Service d6b4c9
  7. ECP conveys <Response> to SP using PAOS
Packit Service d6b4c9
  8. SP grants or denies access to principal
Packit Service d6b4c9
Packit Service d6b4c9
mod_auth_mellon and ECP
Packit Service d6b4c9
-----------------------
Packit Service d6b4c9
Packit Service d6b4c9
mod_auth_mellon plays the role of the SP in an ECP transaction.
Packit Service d6b4c9
Packit Service d6b4c9
mod_auth_mellon utilizes the Lasso library to provide it's SAML2
Packit Service d6b4c9
functionality. Fully functioning SAML2 ECP support in Lasso is
Packit Service d6b4c9
relatively new. When mod_auth_mellon is built it detects the presence
Packit Service d6b4c9
of SAML2 ECP in Lasso and only compiles in the ECP code in
Packit Service d6b4c9
mod_auth_mellon if it's present in Lasso.
Packit Service d6b4c9
Packit Service d6b4c9
How does mod_auth_mellon recognize a request is from an ECP client?
Packit Service d6b4c9
```````````````````````````````````````````````````````````````````
Packit Service d6b4c9
Packit Service d6b4c9
In Step 1. when the ECP client issues the HTTP Request to the SP it
Packit Service d6b4c9
**MUST** include `application/vnd.paos+xml` as a mime type in the HTTP
Packit Service d6b4c9
`Accept` header field and include an HTTP `PAOS` header specifying a
Packit Service d6b4c9
PAOS version of `urn:liberty:paos:2003-08` and an ECP service
Packit Service d6b4c9
declaration of `urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp` [2]_,
Packit Service d6b4c9
for example::
Packit Service d6b4c9
Packit Service d6b4c9
  Accept: text/html, application/vnd.paos+xml
Packit Service d6b4c9
  PAOS: ver="urn:liberty:paos:2003-08";"urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp"
Packit Service d6b4c9
Packit Service d6b4c9
If mod_auth_mellon sees this in the incoming request it knows the
Packit Service d6b4c9
client is ECP aware and capable. If authentication is required
Packit Service d6b4c9
mod_auth_mellon will initiate an ECP flow.
Packit Service d6b4c9
Packit Service d6b4c9
The role of IdP's in ECP
Packit Service d6b4c9
````````````````````````
Packit Service d6b4c9
Packit Service d6b4c9
The SAML2 ECP profile states it is the ECP client which determines the
Packit Service d6b4c9
IdP that will be used for authentication. This is in contrast to the
Packit Service d6b4c9
Web SSO flow where the SP determines the IdP. However, the ECP
Packit Service d6b4c9
protocol permits an SP to send the ECP client a list of IdP's it
Packit Service d6b4c9
trusts. It is optional if the SP sends an IDPList, if it does the ECP
Packit Service d6b4c9
client should select the IdP from the SP provided IDPList otherwise
Packit Service d6b4c9
the ECP client is free to select any IdP it wishes.
Packit Service d6b4c9
Packit Service d6b4c9
If the mellon configuration option `MellonECPSendIDPList` is true then
Packit Service d6b4c9
mod_auth_mellon will include an IDPList when it returns a PAOS
Packit Service d6b4c9
<AuthnRequest> to the ECP client.
Packit Service d6b4c9
Packit Service d6b4c9
To build the IDPList mod_auth_mellon scans it's list of loaded IdP's
Packit Service d6b4c9
selecting those which are ECP capable. To support ECP an IdP must
Packit Service d6b4c9
advertise the SingleSignOn service utilizing the SOAP binding.
Packit Service d6b4c9
Packit Service d6b4c9
ECP specific mod_auth_mellon configuration directives
Packit Service d6b4c9
`````````````````````````````````````````````````````
Packit Service d6b4c9
Packit Service d6b4c9
These configuration directives are specific to ECP:
Packit Service d6b4c9
Packit Service d6b4c9
MellonECPSendIDPList
Packit Service d6b4c9
  If `On` mod_auth_mellon will send an IdP list to the ECP client
Packit Service d6b4c9
  containing only those IdP's capable of ECP flow. The ECP client
Packit Service d6b4c9
  should select an IdP only from this list. If this option is `Off`
Packit Service d6b4c9
  no IdP list will be sent and the ECP client is free to select any
Packit Service d6b4c9
  IdP.
Packit Service d6b4c9
Packit Service d6b4c9
Example ECP client
Packit Service d6b4c9
``````````````````
Packit Service d6b4c9
Packit Service d6b4c9
To illustrate a simple ECP client based on Lasso we'll use the Lasso
Packit Service d6b4c9
Python binding (as opposed to pseudo code, Python is quite
Packit Service d6b4c9
readable). All error checking and another necessary ancillary code has
Packit Service d6b4c9
been eliminated in order to clearly illustrate only the ECP
Packit Service d6b4c9
operations.
Packit Service d6b4c9
Packit Service d6b4c9
.. code-block:: python
Packit Service d6b4c9
Packit Service d6b4c9
  import lasso
Packit Service d6b4c9
  import requests
Packit Service d6b4c9
Packit Service d6b4c9
  ecp = lasso.Ecp(server)
Packit Service d6b4c9
  session = requests.Session()
Packit Service d6b4c9
Packit Service d6b4c9
  MEDIA_TYPE_PAOS = 'application/vnd.paos+xml'
Packit Service d6b4c9
  PAOS_HEADER = 'ver="%s";"%s"' % (lasso.PAOS_HREF,lasso.ECP_HREF)
Packit Service d6b4c9
Packit Service d6b4c9
  # Step 1: Request protected resource, indicate ECP capable
Packit Service d6b4c9
  response = session.get(protected, headers={'Accept': MEDIA_TYPE_PAOS,
Packit Service d6b4c9
                                             'PAOS': PAOS_HEADER})
Packit Service d6b4c9
Packit Service d6b4c9
  # Process returned PAOS wrapped <AuthnRequest>
Packit Service d6b4c9
  ecp.processAuthnRequestMsg(response.text)
Packit Service d6b4c9
Packit Service d6b4c9
  # Post SOAP wrapped <AuthnRequest> to IdP, use Digest Auth to authenticate
Packit Service d6b4c9
  response = session.post(ecp.msgUrl,
Packit Service d6b4c9
                          data=ecp.msgBody,
Packit Service d6b4c9
                          auth=requests.auth.HTTPDigestAuth(user, password)
Packit Service d6b4c9
                          headers={'Content-Type': 'text/xml'})
Packit Service d6b4c9
Packit Service d6b4c9
  # Process returned SOAP wrapped <Assertion> from IdP
Packit Service d6b4c9
  ecp.processResponseMsg(response.text)
Packit Service d6b4c9
Packit Service d6b4c9
  # Post PASO wrapped <Assertion> to SP, response is protected resource
Packit Service d6b4c9
  response = session.post(ecp.msgUrl,
Packit Service d6b4c9
                          data=ecp.msgBody,
Packit Service d6b4c9
                          headers={'Content-Type': 'application/vnd.paos+xml'})
Packit Service d6b4c9
Packit Service d6b4c9
Packit Service d6b4c9
mod_auth_mellon internal ECP implementation notes
Packit Service d6b4c9
-------------------------------------------------
Packit Service d6b4c9
Packit Service d6b4c9
Packit Service d6b4c9
Notes on ECP vs. Web SSO flow
Packit Service d6b4c9
`````````````````````````````
Packit Service d6b4c9
Packit Service d6b4c9
Web SSO (Single Sign-On) flow is by far the most common and what
Packit Service d6b4c9
most people are familiar with when they think of SAML. The Web SSO
Packit Service d6b4c9
profile is designed so that browsers ignorant of SAML can perform
Packit Service d6b4c9
SAML authentication without modification. This is accomplished with
Packit Service d6b4c9
existing HTTP paradigms such as redirects, form posts, etc. which a
Packit Service d6b4c9
browser will process normally yielding the desired result.
Packit Service d6b4c9
Packit Service d6b4c9
ECP (Enhanced Client or Proxy) is a different SAML profile that
Packit Service d6b4c9
also accomplishes SSO (Single Sign-On). The distinction is an ECP
Packit Service d6b4c9
client is fully SAML aware and actively participates in the SAML
Packit Service d6b4c9
conversation.
Packit Service d6b4c9
Packit Service d6b4c9
Web SSO and ECP have very different flows, mod_auth_mellon must
Packit Service d6b4c9
support both flows. mod_auth_mellon is a SP (Service Provider).
Packit Service d6b4c9
Packit Service d6b4c9
IdP Selection Differences
Packit Service d6b4c9
`````````````````````````
Packit Service d6b4c9
Packit Service d6b4c9
With Web SSO the SP determines the IdP and redirects there.
Packit Service d6b4c9
Packit Service d6b4c9
With ECP the ECP client determines the IdP, the SP has no a prori
Packit Service d6b4c9
knowledge of the target IdP, although the SP may provide a
Packit Service d6b4c9
suggested list of IdP's when responding to the ECP client.
Packit Service d6b4c9
Packit Service d6b4c9
Since with ECP it is the ECP client which selects the IdP the set of
Packit Service d6b4c9
IdP's loaded into mod_auth_mellon are not relevant **except** if
Packit Service d6b4c9
`MellonECPSendIDPList` is enabled. In this case mod_auth_mellon will
Packit Service d6b4c9
filter the set of loaded IdP's and forward those IdP's supporting
Packit Service d6b4c9
SingleSignOn with the SOAP binding.
Packit Service d6b4c9
Packit Service d6b4c9
Apache request processing pipeline
Packit Service d6b4c9
``````````````````````````````````
Packit Service d6b4c9
Packit Service d6b4c9
Apache implements a request processing pipeline composed of
Packit Service d6b4c9
stages. An Apache extension module can participate in the pipeline
Packit Service d6b4c9
by asking to be called at specific stages (steps) by registering a
Packit Service d6b4c9
hook function for that stage. Final content returned to the HTTP
Packit Service d6b4c9
client in the HTTP response is generated in the "handler", one of
Packit Service d6b4c9
the final stages in the request processing pipeline.
Packit Service d6b4c9
Packit Service d6b4c9
One of the stages in the request pipeline is determining
Packit Service d6b4c9
authentication and authorization for protected resources. If a
Packit Service d6b4c9
resource is protected and the authentication and authorization
Packit Service d6b4c9
pipeline stages deny access or fail the request processing pipeline
Packit Service d6b4c9
is aborted early, a non-success HTTP response is returned, the
Packit Service d6b4c9
content handler is never reached.
Packit Service d6b4c9
Packit Service d6b4c9
With Web SSO if authentication needs to be performed a redirect will
Packit Service d6b4c9
be returned that redirects to a SAML endpoint (login) on our SP. This
Packit Service d6b4c9
in turn generates the SAML <AuthnRequest> with a redirect to the
Packit Service d6b4c9
IdP. All of this is very vanilla standard HTTP easily accommodated by
Packit Service d6b4c9
Apache's request processing pipeline which is designed to handle these
Packit Service d6b4c9
types of flows.
Packit Service d6b4c9
Packit Service d6b4c9
ECP requires special handling
Packit Service d6b4c9
`````````````````````````````
Packit Service d6b4c9
Packit Service d6b4c9
However ECP has a very different flow. When an ECP client sends a
Packit Service d6b4c9
request to the SP it includes a special HTTP headers indicating it is
Packit Service d6b4c9
ECP capable. If the SP determines the resource is protected and
Packit Service d6b4c9
authentication is needed and the client has signaled it is ECP capable
Packit Service d6b4c9
then the SP responds successfully (200) with a SAML <AuthnRequest>
Packit Service d6b4c9
wrapped in PAOS. *This is very different than conventional HTTP
Packit Service d6b4c9
request processing.* Here we have a case where there is a protected
Packit Service d6b4c9
resource that has **not** been authenticated yet the web server will
Packit Service d6b4c9
responds with an HTTP 200 success and content! One might normally
Packit Service d6b4c9
expect a HTTP 401 or redirect response for a protected resource when
Packit Service d6b4c9
there is no authenticated user. *This is clearly contrary to the
Packit Service d6b4c9
expectations of Apache's request processing pipeline.*
Packit Service d6b4c9
Packit Service d6b4c9
Reaching the Apache content handler
Packit Service d6b4c9
```````````````````````````````````
Packit Service d6b4c9
Packit Service d6b4c9
In order to be able to return a successful (HTTP 200) PAOS response
Packit Service d6b4c9
when doing the ECP we have to reach the part of Apache's request
Packit Service d6b4c9
processing pipeline that generates the response. In Apache terminology
Packit Service d6b4c9
this is called a (content) handler.
Packit Service d6b4c9
Packit Service d6b4c9
At an early stage we detect if authentication is required. For the
Packit Service d6b4c9
normal Web SSO profile we would redirect the client back to our login
Packit Service d6b4c9
endpoint which will be handled by our handler in a different
Packit Service d6b4c9
request. But for ECP the current request must proceed. We set a flag
Packit Service d6b4c9
on the request indicating ECP authentication is required. The pipeline
Packit Service d6b4c9
continues. When the pipeline reaches the authentication and
Packit Service d6b4c9
authorization stages we check the ECP flag on the request, if ECP
Packit Service d6b4c9
authentication is indicated we lie and tell the pipeline the user is
Packit Service d6b4c9
authenticated and authorized. We do this only so we can reach the
Packit Service d6b4c9
handler stage (otherwise because the request is for a protected
Packit Service d6b4c9
resource the pipeline would terminate with an error). Despite our
Packit Service d6b4c9
having forced authentication and authorization to be valid for the
Packit Service d6b4c9
protected resource the request processing pipeline *will not return the
Packit Service d6b4c9
protected resource* because we will subsequently intercept the request
Packit Service d6b4c9
in our handler before the pipeline reaches the point of returning the
Packit Service d6b4c9
protected resource.
Packit Service d6b4c9
Packit Service d6b4c9
At the handler stage
Packit Service d6b4c9
````````````````````
Packit Service d6b4c9
Packit Service d6b4c9
Once our handler is invoked it has 3 possible actions to perform:
Packit Service d6b4c9
Packit Service d6b4c9
  1. The request is for one of our SAML endpoints (e.g. login,
Packit Service d6b4c9
  logout, metadata, etc.) We dispatch to the handler for the specific
Packit Service d6b4c9
  action. We detect this case by matching the request URI to our SAML
Packit Service d6b4c9
  endpoints. We signal to the pipeline that our hook handled the request.
Packit Service d6b4c9
Packit Service d6b4c9
  2. The request is for a protected resource and needs ECP
Packit Service d6b4c9
  authentication performed. We detect this case by examining the ECP flag
Packit Service d6b4c9
  set on the request by an earlier hook function. The request URI is
Packit Service d6b4c9
  for the protected resource and has nothing to do with our SAML
Packit Service d6b4c9
  endpoints. We generate the PAOS <AuthnRequest> and respond with
Packit Service d6b4c9
  success (200) and signal to the pipeline that our hook handled the
Packit Service d6b4c9
  request. Note, we have not returned the protected resource, instead
Packit Service d6b4c9
  we've returned the PAOS request.
Packit Service d6b4c9
Packit Service d6b4c9
  3. The request has nothing to do with us, we decline to handle
Packit Service d6b4c9
  it. The pipeline proceeds to the next handler.
Packit Service d6b4c9
Packit Service d6b4c9
Packit Service d6b4c9
.. [1] The means by which a principal authenticates with an identity
Packit Service d6b4c9
       provider is outside of the scope of SAML. Typically an ECP
Packit Service d6b4c9
       client will utilize an HTTP authentication method when posting
Packit Service d6b4c9
       the <AuthnRequest> SOAP message to the IdP.
Packit Service d6b4c9
Packit Service d6b4c9
.. [2] Contrary to most HTTP headers the values in the PAOS header must
Packit Service d6b4c9
       be enclosed in double quotes. A semicolon is used to separate
Packit Service d6b4c9
       the values.