Blame ECP.rst

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