5226 lines
276 KiB
Plaintext
5226 lines
276 KiB
Plaintext
= mod_auth_mellon User Guide
|
|
John Dennis <jdennis@redhat.com>
|
|
v1.3, 2018-02-22
|
|
:toc: left
|
|
:toclevels: 3
|
|
:numbered:
|
|
:icons: font
|
|
:imagesdir: images
|
|
:data-uri:
|
|
|
|
== Colophon
|
|
|
|
Author: {author} {email}
|
|
|
|
Version: {revnumber}
|
|
|
|
Date: {revdate}
|
|
|
|
== Document Conventions
|
|
|
|
.Example Data used in this document
|
|
****
|
|
|
|
This document contains many examples of SAML data. For consistency we
|
|
will use the following:
|
|
|
|
* The SP is hosted on the node `mellon.example.com`.
|
|
* The SP `MellonEndpointPath` is `/mellon`
|
|
* The SP `entityID` is `https://mellon.example.com/mellon/metadata`
|
|
* Mellon is protecting the URL location `/private` and everything
|
|
under it.
|
|
* The protected resource is `/private/info.html` and hence the URL of
|
|
the protected resource is `https://mellon.example.com/private/info.html`.
|
|
* The IdP is hosted on the node `rhsso.example.com`
|
|
* The IdP `entityID` is `https://rhsso.example.com:8443/auth/realms/test`
|
|
|
|
****
|
|
|
|
== Introduction
|
|
|
|
mod_auth_mellon is an Apache (httpd) authentication module
|
|
providing authentication and authorization services via SAML. Mellon
|
|
plays the role of a _Service Provider_ (SP) in SAML.
|
|
|
|
|
|
== SAML Overview
|
|
|
|
SAML (_Security Assertion Markup Language_) is a framework for exchanging
|
|
security information between providers. The nonprofit
|
|
https://www.oasis-open.org/[OASIS] consortium is responsible for
|
|
defining and publishing the various SAML specifications. OASIS is an
|
|
acronym for _Organization for the Advancement of Structured
|
|
Information Standards_. All SAML specifications and errata can be
|
|
found at this location:
|
|
|
|
https://docs.oasis-open.org/security/saml/v2.0/
|
|
|
|
The SAML technical committee has published the
|
|
https://www.oasis-open.org/committees/download.php/27819/sstc-saml-tech-overview-2.0-cd-02.pdf[Security
|
|
Assertion Markup Language (SAML) V2.0 Technical Overview]. This is an
|
|
excellent high-level overview of SAML and worth reading to familiarize
|
|
yourself with general SAML operation and terminology.
|
|
|
|
SAML is a large complex standard that currently comprises 10 individual
|
|
specifications whose total content is hundreds of pages of printed
|
|
material. SAML is much too large to cover in this overview. Instead we
|
|
will focus on the most common use of SAML, Web Single Sign-On
|
|
(Web-SSO). This is the target focus of mod_auth_mellon, although
|
|
Mellon does support other profiles as well.
|
|
|
|
SAML organizes itself into <<saml_profiles,Profiles>> and
|
|
<<saml_binding,Bindings>>. A cursory overview of these two concepts
|
|
will help you understand SAML better and is especially important if
|
|
you have to refer to any SAML specifications.
|
|
|
|
=== SAML Roles [[saml_roles]]
|
|
|
|
Participants in SAML play different roles. An entity may be capable of
|
|
playing more than one role, however we typically only consider a single role when
|
|
discussing entity behavior. The defined SAML roles are:
|
|
|
|
* Identity Provider (IdP)
|
|
* Service Provider (SP)
|
|
* Affiliation
|
|
* Attribute Authority
|
|
* Attribute Consumer
|
|
* Policy Decision Point
|
|
|
|
Of these we are only interested in Service Providers (SP) and Identity
|
|
Providers (IdP). Mellon is a Service Provider because it provides a
|
|
service to clients. Authentication and user information is provided by
|
|
an Identity Provider. The SP relies on the IdP for its authentication
|
|
needs. In SAML literature you will often see the term _attesting
|
|
party_ or _asserting party_, which in most contexts means an IdP
|
|
because the IdP attests to or asserts certain claims in its role as
|
|
an _authority_. On the other hand a Service Provider is often referred
|
|
to as a _relying party_ because it _relies_ on the _assertions_
|
|
provided by an _authority_.
|
|
|
|
=== SAML Profiles [[saml_profiles]]
|
|
|
|
A SAML profile defines how SAML data is conveyed using
|
|
<<saml_bindings>> on a transport to accomplish a specific task. The
|
|
_Web Browser SSO Profile_ is the best known and the one Mellon focuses
|
|
on. Other profiles include _Single Logout_, _Enhanced Client or Proxy
|
|
(ECP)_, _Identity Provider Discovery_, etc.
|
|
|
|
SAML profiles are defined in the https://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf[Profiles
|
|
for the OASIS Security Assertion Markup Language (SAML) V2.0] specification.
|
|
|
|
=== SAML Bindings [[saml_bindings]]
|
|
|
|
SAML bindings define how SAML messages are mapped onto standard
|
|
messaging or communication protocols. The best way to think of a SAML
|
|
binding is as a transport mechanism. A key concept is that a given
|
|
SAML profile may permit the same SAML message to be conveyed using
|
|
variety of SAML bindings. Or by the same token a SAML profile may
|
|
prohibit the use of certain SAML bindings.
|
|
|
|
SAML bindings are defined in the
|
|
https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf[Bindings
|
|
for the OASIS Security Assertion Markup Language (SAML) V2.0]
|
|
specification.
|
|
|
|
|
|
=== SAML Messages
|
|
|
|
All SAML messages are conveyed as XML documents. A SAML XML message
|
|
may be transported in a variety of mechanisms known as a
|
|
<<saml_bindings, SAML binding>>. Examples of SAML bindings include:
|
|
|
|
* query parameters of an HTTP URL.
|
|
* parameters of an HTML form.
|
|
* wrapped in a SOAP message.
|
|
|
|
The exact way a SAML interchange operates and the SAML bindings which
|
|
are utilized in each step define what is called a SAML
|
|
<<saml_profiles, SAML profile>>. For example web-sso is defined by the
|
|
_Web Browser SSO Profile_.
|
|
|
|
SAML data, and its XML schema are defined in the https://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf[Assertions and Protocols for the OASIS
|
|
Security Assertion Markup Language
|
|
(SAML) V2.0] _core_ specification.
|
|
|
|
=== SAML Web-SSO flow [[web_sso_flow]]
|
|
|
|
The _Web Browser SSO Profile_ is the best known <<saml_profiles,SAML
|
|
profile>> and the one Mellon focuses on. Your ability to configure
|
|
Mellon and diagnose Mellon deployment issues will be greatly enhanced
|
|
if you understand this flow and the two SAML messages conveyed in the
|
|
flow, _SAML AuthnRequest_ and _SAML Assertion Response_.
|
|
|
|
|
|
|
|
image::saml-web-sso.svg[Web Browser SSO Profile]
|
|
|
|
(1) HTTP Request to Service Provider:: A user agent (e.g browser)
|
|
makes a request on behalf of a user for a protected resource hosted by
|
|
the Service Provider (e.g. Mellon). The SP asks if there is an
|
|
existing <<saml_sessions,session>> for the user. A session is
|
|
established by a prior successful SAML authentication. If a valid
|
|
session exists the SP immediately grants access to the protected
|
|
resource. A user session is communicated via a HTTP cookie (see
|
|
<<mellon_cookie>>). If a valid session does not exist the SP begins
|
|
the authentication process.
|
|
|
|
(2) <AuthnRequest> issued by Service Provider to Identity Provider::
|
|
To authenticate the user the SP must send a `<AuthnRequest>` to an
|
|
IdP. In the _Web Browser SSO Profile_ the SP determines the IdP. The
|
|
SP uses the _HTTP Redirect Binding_ to convey the `<AuthnRequest>` to
|
|
the IdP. This binding embeds the `<AuthnRequest>` in the URL query
|
|
parameters of a HTTP redirect. The browser performs a redirect to the
|
|
IdP which decodes the `<AuthnRequest>` embedded in the URL query
|
|
parameters. The IdP also maintains <<saml_sessions,session>>
|
|
information for the user. If there is an existing valid session for
|
|
the user at the IdP it immediately responds with a `<Assertion>`
|
|
response unless the `<AuthnRequest>` has enabled `ForceAuthn` which
|
|
requires the user to be re-authenticated. See the
|
|
<<authentication_request, AuthnRequest example>> to better understand
|
|
its contents and how it appears as HTTP data. Part of the data
|
|
communicated along with the `<AuthnRequest>` is an item known as the
|
|
<<relaystate, RelayState>>. The `RelayState` is the mechanism which
|
|
permits the flow to return to the original requested resource.
|
|
|
|
(3) Identity Provider identifies Principal:: If necessary the IdP
|
|
authenticates the user. How the authentication is performed is *not*
|
|
defined by SAML. Typically the IdP responds with a login page where
|
|
the user enters their username and password. After successful
|
|
authentication the IdP establishes a session for the user.
|
|
|
|
(4) Identity Provider issues a SAML <Response> to the Service Provider::
|
|
Assuming a valid session now exists on the IdP for the user
|
|
it responds to the user's browser with an `<Assertion>` using the _HTTP
|
|
Post Binding_. The HTTP Post binding is a bit magical, you may want to
|
|
review how this works in <<http_post>>. If a valid session could not
|
|
be established for the user a failed status response is issued instead.
|
|
See the <<assertion_response, Assertion example>> to better understand
|
|
the contents of an `<Assertion>`.
|
|
|
|
(5) SP grants or denies access to the principal::
|
|
If the response does not contain a successful `<Assertion>` response
|
|
the SP denies access by returning a 403 HTTP_FORBIDDEN status
|
|
response. Otherwise the SP processes the `<Assertion>`. The SP may
|
|
apply additional constraints on access to the protected resource (see
|
|
<<assertion_constraints, Mellon constraints>> for how Mellon can
|
|
apply additional authorization constraints). If the constraint check
|
|
passes then the SP establishes a session for the user. Mellon
|
|
associates the session information with a session ID returned in a
|
|
cookie (see <<mellon_cookie>>).
|
|
|
|
(6) SP redirects to original resource::
|
|
The SP uses the <<relaystate,RelayState>> which identities the
|
|
original requested resource and responds with a redirect to that URL.
|
|
|
|
(7) Browser accesses resource again::
|
|
The browser upon receiving the redirect to the original resource URL
|
|
once again tries to access the resource. This time however there is a
|
|
valid session established for the user as communicated in the session
|
|
cookie. The SP validates the session ID which should immediately
|
|
succeed. At this point Mellon informs Apache that the authentication
|
|
and authorization check has succeeded for the URL.
|
|
|
|
(8) SP responds with resource::
|
|
Since the authentication and authorization checks in Apache have now
|
|
passed the contents of the resource are returned to the user's browser.
|
|
|
|
==== Sessions [[saml_sessions]]
|
|
|
|
Sessions are maintained at both the SP and the IdP.
|
|
|
|
After an IdP successfully authenticates a user it creates a session
|
|
for the user. The IdP keeps a list of every SP the user is logged
|
|
into. When the user logs out the IdP sends a logout request to the
|
|
_SingleLogoutService_ endpoint of each SP. When an IdP receives a
|
|
`<AuthnRequest>` from a SP it checks to see if it has an existing
|
|
valid session for that user, if so it can skip authenticating the user
|
|
again and instead just issue an `<Assertion>` based on the existing
|
|
session. However the SP can force the IdP to always re-authenticate if
|
|
it passes a `ForceAuthn` value of `True` in the `<AuthnRequest>`. The
|
|
IdP may further be restricted from interacting with the SP if the
|
|
request contains a `isPassive` value of `True`.
|
|
|
|
The IdP can inform the SP how long it wishes a SP session to be valid
|
|
by passing the `SessionNotOnOrAfter` attribute in a
|
|
`<AuthnStatement>`. Mellon respects the `SessionNotOnOrAfter`
|
|
attribute and will limit its session duration based on it.
|
|
|
|
The SP also maintains a session for the user. The SP session is
|
|
communicated between the browser and the SP using a cookie containing
|
|
the session ID. If the SP verifies the user has an existing valid
|
|
session when it receives a request it can immediately make an access
|
|
decision based on the cached session information for the user.
|
|
|
|
See <<mellon_session,Mellon Sessions>> for more information on the
|
|
particulars of how Mellon manages it sessions.
|
|
|
|
|
|
=== HTTP Post and Self-Posting [[http_post]]
|
|
|
|
The _HTTP Post Binding_ is used to convey an assertion back to a
|
|
SP. Assertions are usually too big to embed in a URL so some other
|
|
mechanism is needed to transport the `<Assertion>` response data. The
|
|
data is url-form-encoded as HTTP Form. The form's action attribute
|
|
specifies the destination URL of the form data.
|
|
|
|
Where does the destination URL come from? The IdP will have loaded the
|
|
SP's <<metadata, metadata>> which defines among other things the
|
|
various provider URL <<endpoints,endpoints>> where SAML communication
|
|
occurs. The `<Assertion>` needs to be sent to one of the SP's
|
|
_AssertionConsumerService_ endpoints, specifically the
|
|
_AssertionConsumerService_ endpoint URL supporting the _HTTP-POST_
|
|
binding. The SP's _AssertionConsumerService_ URL as read from its
|
|
metadata is set to the action attribute of the HTTP form. _The action
|
|
URL is *not* read from any data in the <AuthnRequest>_, this is one
|
|
safeguard to prevent SAML messages from being sent to a unintended
|
|
nefarious party. Note that many SAML bindings define a `Destination`
|
|
attribute that is embedded in the SAML message. A further check
|
|
compares the `Destination` attribute to the URL the message was
|
|
received at, see <<invalid_destination>> for a common deployment
|
|
problem.
|
|
|
|
But how does the POST data as received by the user's browser get back
|
|
to the _AssertionConsumerService_ endpoint of the SP? The form will
|
|
_self-post_ due to this:
|
|
|
|
[source,html]
|
|
----
|
|
<body onload="document.forms[0].submit()">
|
|
----
|
|
|
|
As long as the user's browser has not disabled scripts it will
|
|
immediately post the form data to the _AssertionConsumerService_ URL
|
|
in the forms action attribute. If scripts have been disabled the HTML
|
|
will instruct the user to click the `Submit` button to post the form
|
|
data.
|
|
|
|
=== entityID [[entityID]]
|
|
|
|
Each SAML provider (e.g. a SP or IdP) is identified by its
|
|
`entityID`. You should think of the `entityID` as the globally unique
|
|
name of the provider. The `entityID` appears in most SAML messages and
|
|
in the provider's metadata. This is the mechanism by which a SAML
|
|
message consumer associates the SAML message with the message
|
|
producers configuration properties. When a SAML provider receives a
|
|
message it extracts the `entityID` from the message and then looks up
|
|
the metadata belonging to that provider. The information in the
|
|
provider's metadata is essential in order to operate on the SAML
|
|
message.
|
|
|
|
WARNING: Any mismatch between the `entityID` the producer is emitting
|
|
and the consumer has loaded via the producer's metadata will cause
|
|
failures. A common mistake is to modify a producer's metadata
|
|
(e.g. update Mellon) but fail to reload Mellon's metadata in the IdP.
|
|
|
|
SAML places two requirements on the `entityID`:
|
|
|
|
* It *must* be an URI
|
|
* It *must* be unique within the federation
|
|
|
|
A wise administrator will also seek to fulfill this additional
|
|
requirement when choosing an `entityID`:
|
|
|
|
* It should identify the organization instead of a specific node
|
|
within the organization.
|
|
|
|
When migration time arrives it is far easier to move resources around
|
|
when those resources are not tied to a specific node. Thus choosing an
|
|
`entityID` comprised of the organization's domain name and a generic
|
|
identifier such as `saml` would be one good approach, for example
|
|
`https://bigcorp.com/saml`.
|
|
|
|
A common practice and one that recommended in the
|
|
https://docs.oasis-open.org/security/saml/v2.0/saml-metadata-2.0-os.pdf[Metadata
|
|
for the OASIS Security Assertion Markup Language (SAML)] specification
|
|
in section 4, _Metadata Publication and Resolution_ is to use the
|
|
`entityID` as a _well-known-location_ for retrieving the provider's
|
|
metadata. In other words the `entityID` is the URL which returns the
|
|
provider's XML metadata document when a HTTP GET is performed on that
|
|
URL. _It is not a requirement the `entityID` be the URL for metadata
|
|
download_ rather it is one common convention. As discussed in the SAML
|
|
metadata specification other mechanisms can be established for
|
|
metadata publication.
|
|
|
|
IMPORTANT: SAML requires metadata publication to be integrity
|
|
protected. A provider's metadata is literally the _keys to the
|
|
provider's kingdom_ as it contains the cryptographic keys used during
|
|
SAML authentication as well as other vital SAML properties. _It is
|
|
essential to establish trust and validate the metadata._ Metadata can
|
|
be signed but the easiest way to assure metadata integrity and the
|
|
most common is to make sure metadata is only exchanged via a secure
|
|
and trusted channel. TLS provides such a mechanism. Therefore if you
|
|
publish metadata (and Mellon always does regardless of whether Mellon's
|
|
metadata endpoint matches Mellon's `entityID`) it *_MUST_* occur
|
|
_only_ over the `https` TLS scheme. Make sure your Apache
|
|
configuration redirects any `http` for Mellon to `https` and that your
|
|
https certificate is signed by a trusted CA such that others can
|
|
properly validate your https cert. _Do not use self-signed certs for
|
|
your https!_ If you do and you're on a public network, you're
|
|
opening yourself up to a serious security vulnerability. Note, the
|
|
certs used _inside_ the metadata can be self-signed, see
|
|
<<metadata_keys>> for an explanation of why. The key concept here to take
|
|
away is that _a provider's metadata provides the trust and is the validation
|
|
mechanism used by SAML_. Thus the integrity of the metadata is of
|
|
paramount importance.
|
|
|
|
Mellon's metadata is _always_ published at the URL location
|
|
`/$MellonEndpointPath/metadata`. See the description of
|
|
<<mellon_endpoint_path, MellonEndpointPath>> for more details on the
|
|
use of MellonEndpointPath. This is why most of the tools surrounding
|
|
Mellon generate an `entityID` as the concatenation of the https
|
|
scheme, the hostname, the MellonEndpointPath and "metadata". Thus for
|
|
example if the `MellonEndpointPath` for `bigcorp.com` was set to
|
|
`saml`, the `entityID` (the URL location for downloading its
|
|
metadata) would be `https://bigcorp.com/saml/metadata`. The only reason
|
|
why "metadata" appears in the `entityID` is because that is Mellon's
|
|
URL endpoint for metadata publication.
|
|
|
|
=== Username, userid, SAML NameID [[name_id]]
|
|
|
|
==== Userid vs. Identity (or why userid is so last millennium)
|
|
|
|
Many people struggle with the notion of _userid_ when working with
|
|
SAML (or any other federated identity system). That's because
|
|
historically _userid_ has been used to describe _identity_. The two
|
|
are not the same. _Identity_ identifies who or what something is for
|
|
the purpose of authentication and authorization as well as binding
|
|
attributes to that identity. In most of the literature the terms
|
|
_subject_ and _principal_ are used interchangeably to encapsulate the
|
|
concept of who or what is being identified. Although a
|
|
subject is often a person it need not be, it might also be an
|
|
inanimate object. A good example of a non-human subject would be a
|
|
computer service needing to be authenticated in order to perform
|
|
an operation.
|
|
|
|
Userids grew out of the early days of computing when all computing
|
|
was local and users were given accounts on a local system. The userid
|
|
was how operating systems tracked who a user was, in most cases it was
|
|
an integer. Clearly the integer userid only had meaning in the context
|
|
of the local system. As systems became networked integer userids
|
|
would be shared between systems but fundamentally nothing had changed,
|
|
the userid was still meaningful only among a group of cooperating
|
|
computers. Tools such as Yellow Pages, NIS, LDAP and Active Directory
|
|
were developed to provide a centralized repository of userids that
|
|
could be shared between cooperating networked computers. Along the way
|
|
the integer userid morphed into a string often partitioned into a
|
|
local part and a domain part. The domain part is used to identify the
|
|
realm. Realms are nothing other than collections of _unique_ userids
|
|
often serving the needs of a organizational unit (e.g. company or
|
|
institution).
|
|
|
|
A key concept is that whoever is providing the userid, whether it be local
|
|
accounts created by the host operating system or a network provider of
|
|
userids such as NIS or LDAP, is an *identity provider* (IdP) with the
|
|
_userid_ being the *key* used by _that_ specific
|
|
*identity provider* to look up the *identity*. Hence _userids are only
|
|
meaningful in the context of a specific IdP!_
|
|
|
|
By definition _federated identity_ is the amalgamation of diverse
|
|
unrelated identity providers, each of which utilizes its own userid as
|
|
a key to look up an identity. Therefore while deploying federated
|
|
identity if you cling to the concept of a single userid you are likely to
|
|
be frustrated because you are abusing the concept.
|
|
|
|
==== How SAML identifies a subject [[saml_nameid]]
|
|
|
|
In SAML the user name (principal or subject) is conveyed as part of
|
|
the `<Subject>` element in the assertion. The subject identifier can
|
|
be any one of these elements:
|
|
|
|
* `<BaseID>`
|
|
* `<NameID>`
|
|
* `<EncryptedID>`
|
|
|
|
The most common is `<NameID>` and it usually includes a `Format`
|
|
attribute. If the `Format` attribute is absent then it defaults to the
|
|
unspecified `Format`. The `Format` attribute tells you how to interpret
|
|
the `NameID` value. For example if the subject's `NameID` format is
|
|
`urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress` you know the
|
|
subject is being identified by their email address.
|
|
|
|
The currently defined `NameID` formats are:
|
|
|
|
Unspecified::
|
|
This is used when you don't care what the `NameID` `Format` is, you're
|
|
willing to accept whatever it defaults to by the provider.
|
|
(`urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified`)
|
|
|
|
Email Address::
|
|
The `NameID` is an email address as specified in RFC 2822 as a
|
|
`addr-spec` in the form `local-part@domain`. No common name
|
|
or other text is included and it is not enclosed in `<` and `>`.
|
|
(`urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`)
|
|
|
|
X.509 Subject Name::
|
|
The `NameID` is an X.509 subject name in the form specified for the
|
|
`<ds:X509SubjectName>` element in the XML Signature Recommendation.
|
|
(`urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName`)
|
|
|
|
Windows Domain Qualified Name::
|
|
The `NameID` is a Windows domain qualified name. A Windows domain
|
|
qualified user name is a string of the form "DomainName\UserName". The
|
|
domain name and "\" separator MAY be omitted.
|
|
(`urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName`)
|
|
|
|
Kerberos Principal Name::
|
|
The `NameID` is in the form of a Kerberos principal name using the
|
|
format name[/instance]@REALM.
|
|
(`urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos`)
|
|
|
|
Persistent Identifier:: The `NameID` is a _persistent_ opaque
|
|
identifier for a principal that is specific to an identity provider
|
|
and a service provider or affiliation of service providers. Opaque
|
|
means you cannot (easily) map the id to a user. In many cases the
|
|
persistent id is implemented as a random number or random
|
|
string. Persistent means you'll always get the exact same `NameID` for
|
|
the same subject. Refer to <<nameid_policy,NameIDPolicy>> and its
|
|
`AllowCreate` attribute to understand if the IdP is allowed to create
|
|
a persistent id for the subject if it has not already done so.
|
|
(`urn:oasis:names:tc:SAML:2.0:nameid-format:persistent`)
|
|
|
|
Transient Identifier::
|
|
The `NameID` is an opaque _temporary_ id. Opaque means you cannot
|
|
(easily) map the id to a user. In many cases it's implemented as a
|
|
random number or random string. Temporary means the id is valid _only_ in the
|
|
context of the assertion response which contains it. Think of a
|
|
transient id as a one-time id that cannot be used again or referred to
|
|
again.
|
|
(`urn:oasis:names:tc:SAML:2.0:nameid-format:transient`)
|
|
|
|
IMPORTANT: The important concept here is that SAML's `NameID` as used to
|
|
identify a subject is not the traditional userid you are probably
|
|
used to. Furthermore SAML's `NameID` _may_ only be meaningful to the IdP
|
|
which issued it.
|
|
|
|
==== Burden of interpreting NameID falls to the relying party [[nameid_interpretation]]
|
|
|
|
Ultimately the SP needs to provide some sort of _userid_ the
|
|
application it is hosting can utilize. _Only the application knows what it
|
|
needs!_
|
|
|
|
Let's take the example of an application which wishes to
|
|
identify its users by email address. There are two basic ways you can
|
|
do this with SAML.
|
|
|
|
1. Specify a `NameIDPolicy` of
|
|
`urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress` when the SP
|
|
submits a `<AuthnRequest>` to the IdP. This tells the IdP you want the
|
|
subject's `NameID` to be their email address.
|
|
|
|
2. Ignore the `NameID` returned in the assertion entirely, instead use
|
|
the assertion's `email` attribute.
|
|
|
|
Solution #2 is very important to understand as it illustrates how many
|
|
organizations utilize SAML: they _build an identity from the
|
|
attributes bound to a subject_. They can use one or more attributes to
|
|
build a userid meaningful to the application. They may even require
|
|
the IdP return an attribute unique to the subject across a federation,
|
|
in this instance all IdPs in the federation must support that
|
|
attribute (this is just one approach). The `NameID` is *not* utilized
|
|
in solution #2 in large part because the `NameID` is likely to be
|
|
uniquely bound to the given IdP. This is why SAML's _transient_
|
|
identifiers are often used: it simply does not matter what the
|
|
`NameID` is because the SP is not utilizing it therefore it can be any
|
|
random one-time value.
|
|
|
|
It is also important to understand either the `NameID` _or_ the set of
|
|
attributes _or both_ can be used to ultimately derive an identity to
|
|
pass to the application.
|
|
|
|
Another approach is to utilize SAML's _persistent id_ with the
|
|
observation that the pair (IdP, persistent id) always uniquely
|
|
and repeatably identifies the subject. The SP can maintain a table
|
|
that maps the (IdP, persistent id) pair to an
|
|
application-specific _identity_ using this technique.
|
|
|
|
==== How Mellon handles the NameID
|
|
|
|
Mellon extracts the `<NameID>` element from the
|
|
assertion's `<Subject>` element and sets this to `NAME_ID` attribute. If
|
|
`<NameID>` is absent in the assertion you can change what Mellon
|
|
considers the user name to be to another value in one of the
|
|
assertions attributes if you wish. `MellonUser` names the attribute
|
|
you wish to use instead. If you want to export the username as
|
|
`REMOTE_USER` so your web app can process this very common CGI
|
|
variable see <<set_remote_user>>
|
|
|
|
NOTE: Please be aware that blindly exporting the SAML `NameID` to the
|
|
application may or may not be appropriate for the application. See the
|
|
explanation of <<nameid_interpretation,NameID interpretation>> to
|
|
understand the issues.
|
|
|
|
==== How do you specify the NameID format in SAML? [[specify_mellon_nameid]]
|
|
|
|
In SAML there are 2 configuration options related to the use of
|
|
`NameID`:
|
|
|
|
+1.+ A provider declares which `NameID` formats it supports in its
|
|
<<metadata,metadata>> via the `<NameIDFormat>` element.
|
|
The following metadata excerpt illustrates a provider
|
|
which supports the `transient`, `persistent` and `X509SubjectName`
|
|
formats:
|
|
|
|
[source,xml]
|
|
----
|
|
<NameIDFormat>
|
|
urn:oasis:names:tc:SAML:2.0:nameid-format:transient
|
|
</NameIDFormat>
|
|
<NameIDFormat>
|
|
urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
|
|
</NameIDFormat>
|
|
<NameIDFormat>
|
|
urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName
|
|
</NameIDFormat>
|
|
----
|
|
|
|
+2.+ The SP indicates to the IdP in its `<AuthnRequest>` what `NameID`
|
|
format it wants returned via the `<NameIDPolicy>` element. The
|
|
`<NameIDPolicy>` should be one of the `NameIDFormat` elements
|
|
enumerated in the IdP's metadata. The IdP is free to substitute
|
|
another `NameID` format or to return an `InvalidNameIDPolicy` error
|
|
status response if it can't satisfy the request. [[nameid_policy]]
|
|
|
|
IMPORTANT: Mellon defaults to a `NameIDFormat` of `transient` when it
|
|
<<metadata_creation,generates its metadata>>. You will need to
|
|
manually edit the `NameIDFormat` in your Mellon SP metadata if you
|
|
wish to use a `NameIDFormat` other than `transient`. When Mellon
|
|
generates its `<AuthnRequest>` it selects the _first_ `NameIDFormat`
|
|
found in its metadata as the `NameIDPolicy`.
|
|
|
|
|
|
=== <AuthnRequest> Example [[authentication_request]]
|
|
|
|
Here is an example `<AuthnRequest>` as emitted by Mellon.
|
|
|
|
[source,xml]
|
|
----
|
|
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
|
|
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
|
|
ID="_59126C3306E4679F653022F0C4DA7F04" <!--1-->
|
|
Version="2.0"
|
|
IssueInstant="2017-06-28T13:39:14Z" <!--2-->
|
|
Destination="https://rhsso.example.com:8443/auth/realms/test/protocol/saml" <!--3-->
|
|
Consent="urn:oasis:names:tc:SAML:2.0:consent:current-implicit"
|
|
ForceAuthn="false" <!--4-->
|
|
IsPassive="false" <!--5-->
|
|
AssertionConsumerServiceURL="https://mellon.example.com/mellon/postResponse" <!--6-->
|
|
>
|
|
<saml:Issuer>https://mellon.example.com/mellon/metadata</saml:Issuer> <!--7-->
|
|
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" <!--8-->
|
|
AllowCreate="true"/> <!--9-->
|
|
</samlp:AuthnRequest>
|
|
----
|
|
|
|
<1> `ID`: Unique ID generated by Mellon to identify the SAML
|
|
request. It will appear in the SAML response in the `InResponseTo`
|
|
attribute. Used to correlate SAML request and responses.
|
|
|
|
<2> `IssueInstant`: Timestamp of when request was made
|
|
|
|
<3> `Destination`: Where this request was sent to. Used as a
|
|
protection to prevent malicious forwarding of requests to unintended
|
|
recipients. The recipient verifies the URL where it received the SAML
|
|
request matches the `Destination`.
|
|
|
|
<4> `ForceAuthn`: If true the IdP *must* authenticate the principal
|
|
instead of relying on an existing session for the principal.
|
|
|
|
<5> `IsPassive`: If true neither the user agent (browser) nor the IdP
|
|
may take control of the user interface.
|
|
|
|
<6> `AssertionConsumerServiceURL`: Where to send the assertion
|
|
response (see <<sp_metadata_acs, SP metadata AssertionConsumerService
|
|
for HTTP-POST binding>> to see where this was defined.
|
|
|
|
<7> `Issuer`: The SP which issued the AuthnRequest. See
|
|
<<sp_metadata_entityid, SP metadata Issuer>> to see where this was
|
|
defined. Also see the general description of <<entityId,SAML Entity ID's>>
|
|
|
|
<8> `NameIDPolicy`: The SP requests that the Subject returned in the
|
|
assertion be identified by a transient name. See <<name_id>> for more
|
|
details.
|
|
|
|
<9> `AllowCreate`: If true then the IdP is allowed to create a new
|
|
identifier for the principal.
|
|
|
|
The `<AuthnRequest>` is sent using the _HTTP Redirect Binding_. The
|
|
above `<AuthnRequest>` appears on the wire as a URL with the SAML
|
|
data embedded as query parameters. You can see the "on the wire" HTTP
|
|
data for this `<AuthnRequest>` in
|
|
<<authentication_request_wire>>. This illustrates the need for SAML
|
|
diagnostic tools because you cannot see the `<AuthnRequest>` XML
|
|
message and its assocated data (e.g. signature, <<relaystate,
|
|
RelayState>>) by looking at the HTTP protocol.
|
|
|
|
|
|
=== <Assertion> Example [[assertion_response]]
|
|
|
|
This is an example of an `<Assertion>` response as generated by a Red
|
|
Hat SSO server (Keycloak) in response to the above
|
|
<<authentication_request>>.
|
|
|
|
[source,xml]
|
|
----
|
|
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" <!--1-->
|
|
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
|
|
Destination="https://mellon.example.com/mellon/postResponse" <!--2-->
|
|
ID="ID_d06daaaf-64ec-44d3-95a7-08da893aa9d5" <!--3-->
|
|
InResponseTo="_59126C3306E4679F653022F0C4DA7F04" <!--4-->
|
|
IssueInstant="2017-06-28T13:39:27.331Z" <!--5-->
|
|
Version="2.0">
|
|
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://rhsso.example.com:8443/auth/realms/test</saml:Issuer> <!--6-->
|
|
<dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"> <!--7-->
|
|
<dsig:SignedInfo>
|
|
<dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
|
|
<dsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
|
|
<dsig:Reference URI="#ID_d06daaaf-64ec-44d3-95a7-08da893aa9d5"> <!--8-->
|
|
<dsig:Transforms>
|
|
<dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
|
|
<dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
|
|
</dsig:Transforms>
|
|
<dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
|
|
<dsig:DigestValue>V/3iYohGv2Ot7pzy6q/BfAdXgSxmdCD7K+XEmFIZlUs=</dsig:DigestValue>
|
|
</dsig:Reference>
|
|
</dsig:SignedInfo>
|
|
<dsig:SignatureValue>...</dsig:SignatureValue>
|
|
<dsig:KeyInfo>
|
|
<dsig:KeyName>1VPndjfABB6S4lb4zwMLjBUhxfzPFnfrvNYvRgcxiUM</dsig:KeyName>
|
|
<dsig:X509Data>
|
|
<dsig:X509Certificate>...</dsig:X509Certificate>
|
|
</dsig:X509Data>
|
|
<dsig:KeyValue>
|
|
<dsig:RSAKeyValue>
|
|
<dsig:Modulus>...</dsig:Modulus>
|
|
<dsig:Exponent>AQAB</dsig:Exponent>
|
|
</dsig:RSAKeyValue>
|
|
</dsig:KeyValue>
|
|
</dsig:KeyInfo>
|
|
</dsig:Signature>
|
|
<samlp:Status> <!--9-->
|
|
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
|
|
</samlp:Status>
|
|
<saml:Assertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion" <!--10-->
|
|
ID="ID_c463a141-d471-40c3-860a-6559ce0a3556"
|
|
IssueInstant="2017-06-28T13:39:27.331Z"
|
|
Version="2.0"
|
|
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
|
|
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://rhsso.example.com:8443/auth/realms/test</saml:Issuer> <!--11-->
|
|
<dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"> <!--12-->
|
|
<dsig:SignedInfo>
|
|
<dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
|
|
<dsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
|
|
<dsig:Reference URI="#ID_c463a141-d471-40c3-860a-6559ce0a3556"> <!--13-->
|
|
<dsig:Transforms>
|
|
<dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
|
|
<dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
|
|
</dsig:Transforms>
|
|
<dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
|
|
<dsig:DigestValue>w8bELRshtX7xHcwZCdglgfpyYBMJmVQJALPAclHHbLA=</dsig:DigestValue>
|
|
</dsig:Reference>
|
|
</dsig:SignedInfo>
|
|
<dsig:SignatureValue>...</dsig:SignatureValue>
|
|
<dsig:KeyInfo>
|
|
<dsig:KeyName>1VPndjfABB6S4lb4zwMLjBUhxfzPFnfrvNYvRgcxiUM</dsig:KeyName>
|
|
<dsig:X509Data>
|
|
<dsig:X509Certificate>...</dsig:X509Certificate>
|
|
</dsig:X509Data>
|
|
<dsig:KeyValue>
|
|
<dsig:RSAKeyValue>
|
|
<dsig:Modulus>...</dsig:Modulus>
|
|
<dsig:Exponent>AQAB</dsig:Exponent>
|
|
</dsig:RSAKeyValue>
|
|
</dsig:KeyValue>
|
|
</dsig:KeyInfo>
|
|
</dsig:Signature>
|
|
<saml:Subject> <!--14-->
|
|
<saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" <!--15-->
|
|
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
|
|
G-803528aa-2f9e-454b-a89c-55ee74e75d1e
|
|
</saml:NameID>
|
|
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
|
|
<saml:SubjectConfirmationData InResponseTo="_59126C3306E4679F653022F0C4DA7F04"
|
|
NotOnOrAfter="2017-06-28T13:44:25.331Z"
|
|
Recipient="https://mellon.example.com/mellon/postResponse"/>
|
|
</saml:SubjectConfirmation>
|
|
</saml:Subject>
|
|
<saml:Conditions NotBefore="2017-06-28T13:39:25.331Z"
|
|
NotOnOrAfter="2017-06-28T13:40:25.331Z">
|
|
<saml:AudienceRestriction>
|
|
<saml:Audience>https://mellon.example.com/mellon/metadata</saml:Audience>
|
|
</saml:AudienceRestriction>
|
|
</saml:Conditions>
|
|
<saml:AuthnStatement AuthnInstant="2017-06-28T13:39:27.332Z"
|
|
SessionIndex="9b6a46b9-28f2-4ce1-b151-713240520e5d">
|
|
<saml:AuthnContext>
|
|
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef>
|
|
</saml:AuthnContext>
|
|
</saml:AuthnStatement>
|
|
<saml:AttributeStatement> <!--16-->
|
|
<saml:Attribute FriendlyName="List of groups" <!--17-->
|
|
Name="groups"
|
|
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
|
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" <!--18-->
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:type="xs:string">ipausers</saml:AttributeValue>
|
|
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" <!--18-->
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:type="xs:string">openstack-users</saml:AttributeValue>
|
|
</saml:Attribute>
|
|
<saml:Attribute FriendlyName="email"
|
|
Name="email"
|
|
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"`>
|
|
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:type="xs:string">jdoe@music.com</saml:AttributeValue>
|
|
</saml:Attribute>
|
|
<saml:Attribute FriendlyName="Display Name"
|
|
Name="display_name"
|
|
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
|
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:type="xs:string">John Doe</saml:AttributeValue>
|
|
</saml:Attribute>
|
|
<saml:Attribute FriendlyName="initials"
|
|
Name="initials"
|
|
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
|
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:type="xs:string">JD</saml:AttributeValue>
|
|
</saml:Attribute>
|
|
<saml:Attribute FriendlyName="Last Name"
|
|
Name="last_name"
|
|
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
|
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:type="xs:string">Doe</saml:AttributeValue>
|
|
</saml:Attribute>
|
|
<saml:Attribute FriendlyName="First Name"
|
|
Name="first_name"
|
|
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
|
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:type="xs:string">John</saml:AttributeValue>
|
|
</saml:Attribute>
|
|
<saml:Attribute Name="Role"
|
|
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
|
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:type="xs:string">uma_authorization</saml:AttributeValue>
|
|
</saml:Attribute>
|
|
<saml:Attribute Name="Role"
|
|
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
|
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:type="xs:string">manage-account</saml:AttributeValue>
|
|
</saml:Attribute>
|
|
<saml:Attribute Name="Role"
|
|
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
|
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:type="xs:string">view-profile</saml:AttributeValue>
|
|
</saml:Attribute>
|
|
</saml:AttributeStatement>
|
|
</saml:Assertion>
|
|
</samlp:Response>
|
|
----
|
|
|
|
<1> `Response`: The `<Response>` element contains the entire SAML
|
|
response, which includes information concerning who issued the
|
|
response, when the response was issued, optionally a signature on the
|
|
response, and the actual response contents which in this case is an
|
|
`<Assertion>`.
|
|
|
|
<2> `Destination`: The _AssertionConsumerService_ endpoint where this
|
|
response will be sent. The receiver will verify it arrived at this
|
|
location or it will reject it.
|
|
|
|
<3> `ID`: Unique ID generated by Mellon to identify the SAML
|
|
request. It will appear in the SAML response in the `InResponseTo`
|
|
attribute. Used to correlate SAML request and responses.
|
|
|
|
<4> `InResponseTo`: This identifies the SAML request being responded
|
|
to. It matches the `ID` attribute in the
|
|
<<authentication_request>>. This is how SAML requests and responses are
|
|
associated with one another as a pair.
|
|
|
|
<5> `IssueInstant`: Timestamp of when response was made.
|
|
|
|
<6> `Issuer`: The IdP which is issuing this response. It is the
|
|
<<entityID>> of the IdP as defined in the <<idp_metadata>>.
|
|
|
|
<7> `Signature`: This response is signed by the IdP. The signature
|
|
information is contained in this XML element.
|
|
|
|
<8> `Reference`: Identifies the XML element being signed. In this
|
|
instance since the signature reference points to the top level
|
|
`<samlp:Response>` the entire response is signed.
|
|
|
|
<9> `Status`: The status of the SAML response. Because in this
|
|
instance the status is `urn:oasis:names:tc:SAML:2.0:status:Success`,
|
|
the authentication was successful. If it had not been, an error status
|
|
would have been returned. *The <Status> element is where to look for the
|
|
success or failure of a SAML request.*
|
|
|
|
<10> `Assertion`: This begins the assertion data. It represents the
|
|
_content_ of the SAML response.
|
|
|
|
<11> `Issuer`: The IdP which is issuing this response. It is the
|
|
<<entityID>> of the IdP as defined in the <<idp_metadata>>
|
|
|
|
<12> `Signature`: The signature on the `<Assertion>`. Note this is
|
|
independent of the signature on the response.
|
|
|
|
<13> `Reference`: Identifies the XML element being signed. In this
|
|
instance the signature reference points to the `<Assertion>` element,
|
|
because that element has the matching `ID` attribute.
|
|
|
|
<14> `Subject`: This begins the `<Subject>` element which identifies
|
|
the principal being authenticated in this `<Assertion>`.
|
|
|
|
<15> `NameID`: *This is where Mellon obtains the username in the
|
|
assertion.* Because the format is `transient` it is a random value
|
|
assigned by the IdP. Note the `MELLON_NAME_ID` in the Apache
|
|
environment exactly matches this. See <<name_id>> for more details.
|
|
|
|
<16> `AttributeStatement`: This begins the *set of attributes* supplied
|
|
by the IdP.
|
|
|
|
<17> `Attribute`: This is the attribute whose `name` is _groups_. It is a
|
|
multi-valued attribute because it contains 2 `<AttributeValue>`
|
|
elements. This attribute could be written in pseudo-code as
|
|
`groups=["ipausers","openstack-users"]`.
|
|
|
|
<18> `AttributeValue`: These are the values for the attribute. In this
|
|
instance there are 2 values, _ipausers_ and _openstack-users_.
|
|
|
|
The above `<Assertion>` response is conveyed back to the SP using the
|
|
_HTTP Post Binding_. You may wish to review <<http_post>>. The "on the
|
|
wire" version of this `<Assertion>` response and its associated
|
|
parameters can be seen in <<assertion_response_wire>>. Once again we see
|
|
the need for SAML tools because it is impossible to view the XML
|
|
message and its associated parameters give the contents of the HTTP
|
|
response.
|
|
|
|
=== SAML Endpoints [[endpoints]]
|
|
|
|
When two SAML providers communicate they must know the URL to send a
|
|
given SAML message to. The set of URLs where a provider receives SAML
|
|
messages is often referred to as its SAML endpoints. Although a SAML
|
|
endpoint may appear in a SAML message, this is *not sufficient* to
|
|
identify where a response should be sent. This is because a nefarious
|
|
sender could insert a bogus location in the message. To assure SAML
|
|
messages are only exchanged between the expected parties, the message
|
|
endpoints are established outside of the message exchange via a
|
|
trusted mechanism when a relationship is initially established between
|
|
the two providers. Although not mandated, this is almost always
|
|
accomplished via the exchange of SAML <<metadata, metadata>> forming a
|
|
trust relationship between the two providers. The presence of a SAML
|
|
endpoint in a SAML message is typically there to validate the message
|
|
against the previously established trust information. Also as you will
|
|
learn below, an endpoint must be paired with a binding type, which is
|
|
another reason why an endpoint appearing in a SAML message is not
|
|
sufficient to establish a communication pathway.
|
|
|
|
A SAML endpoint is defined by a (service,binding)
|
|
pair. The service component identifies what action is hosted by this
|
|
endpoint. Examples of common SAML services you are likely to encounter
|
|
are:
|
|
|
|
SingleSignOnService::
|
|
Authenticate a user and establish a session for them. This is an IdP
|
|
service, it's where a SP sends its `<AuthnRequest>` message.
|
|
|
|
AssertionConsumerService::
|
|
This is where SPs receive `<Assertion>` messages from an IdP in
|
|
response to a `<AuthnRequest>` message.
|
|
|
|
SingleLogoutService::
|
|
Terminate a user's session by logging them out. Both SPs and IdPs
|
|
support this.
|
|
|
|
The binding component of a (service,binding) pair identifies the format
|
|
of the message. Recall that SAML offers many different ways to encode
|
|
the XML of a SAML message. The binding component allows the receiver
|
|
to know how to decode and parse the SAML message back into an XML SAML
|
|
document received at its service endpoint.
|
|
|
|
It's important to understand there is no requirement for a SAML
|
|
provider to locate all its (service,binding) pairs on distinct
|
|
URLs. It is possible to apply heuristics to a SAML message to
|
|
identify the binding of the message arriving on a given URL. This
|
|
allows a provider to collapse its set of endpoints into a smaller set
|
|
of URLs The choice of how a provider maps its endpoints to URLs is
|
|
entirely up to the provider. A common mistake is to assume that because
|
|
one provider does it one way all providers follow the same model. The
|
|
only way for you to know is to examine the providers metadata (see
|
|
<<metadata>>)
|
|
|
|
=== Relay State (How you return to the original URL) [[relaystate]]
|
|
|
|
If you've ever wondered how after all the redirections, posts,
|
|
etc. involved in Web-SSO one finally returns back to the original
|
|
requested resource, you will find the answer in SAML's `RelayState`
|
|
parameter. The `RelayState` is set by the SP when it first initiates
|
|
authentication. SAML requires every party that handles a SAML message
|
|
to preserve the `RelayState` and ultimately return it to the original
|
|
requester. Officially SAML constrains the `RelayState` to a maximum of
|
|
80 bytes and recommends it be integrity protected and not expose
|
|
sensitive information because it often appears in the URL of SAML
|
|
messages. This could be achieved by pairing the URL with a random
|
|
string, using the random string as the `RelayState`, and then obtaining the
|
|
original URL by performing a look-up. However in practice most SAML
|
|
clients set the `RelayState` to the resource URL. This is what Mellon
|
|
currently does.
|
|
|
|
When you are examining SAML messages, the `RelayState` will be the
|
|
original URL and depending on the SAML binding it may be
|
|
URL-encoded. _Just be aware that there is no requirement the `RelayState` be
|
|
the original URL. It can be any string that the client can use
|
|
to establish the context._ At some future date Mellon may alter its
|
|
`RelayState` handling.
|
|
|
|
=== The Role of Metadata [[metadata]]
|
|
|
|
When a SAML provider needs to interact with another SAML provider they
|
|
must know various properties of the foreign provider (i.e. its
|
|
configuration). SAML provider properties are encapsulated in an XML
|
|
document called SAML metadata. Examples of the provider properties
|
|
conveyed in metadata include:
|
|
|
|
* <<entityID,entityID>> (the unique name of the provider)
|
|
* Organizational information
|
|
* The roles this provider offers (e.g. SP, IdP, etc.)
|
|
* <<endpoints,endpoints>> for message exchange
|
|
* X509 certificates the provider uses and for what purpose
|
|
* Should messages be signed
|
|
* Attributes and attribute profiles
|
|
|
|
Typically at start-up a provider loads its own metadata (to configure
|
|
itself) and then loads the metadata of all providers it interacts
|
|
with.
|
|
|
|
The SAML metadata specification can be found here:
|
|
https://docs.oasis-open.org/security/saml/v2.0/saml-metadata-2.0-os.pdf
|
|
|
|
It is vital that SAML metadata be trusted. The SAML specifications do not
|
|
prescribe how metadata is exchanged in a trusted fashion. Many
|
|
providers offer a URL where their metadata can be downloaded from (see
|
|
<<mellon_endpoints>>). Metadata can be signed by the
|
|
provider, which establishes authenticity. Some SAML practitioners do
|
|
not approve of downloading metadata and instead insist upon the
|
|
private exchange of metadata as a means to assure the metadata is
|
|
valid, thus providing a higher level of trust.
|
|
|
|
*Practical field experience has demonstrated that the vast majority of SAML
|
|
problems are due to invalid metadata. Therefore the ability to
|
|
diagnose SAML problems demands the ability to read and understand SAML
|
|
metadata.*
|
|
|
|
To that end let's explore the provider metadata used in our examples.
|
|
|
|
==== Certs and Keys Inside Metadata [[metadata_keys]]
|
|
|
|
Cryptographic keys are used in SAML to sign pieces of data providing
|
|
integrity protection and to encrypt data to provide
|
|
confidentiality. In order for two SAML providers to successfully
|
|
exchange SAML messages between themselves they must know the public
|
|
keys of the other party. The provider's public keys are declared in
|
|
its metadata and are always encapsulated inside a
|
|
`<md:KeyDescriptor>` element that defines its intended use (signing
|
|
or encryption). Furthermore one or more of the following
|
|
representations within a `<ds:KeyInfo>` element *MUST* be present:
|
|
|
|
* `<ds:KeyValue>`
|
|
* `<ds:X509Certificate>` (child element of `<ds:X509Data>`)
|
|
|
|
_The (common) use of a `<ds:X509Certificate>` element is merely a
|
|
notational convenience to encapsulate a key. SAML never utilizes any
|
|
PKI information inside an X509 certificate; the only data SAML
|
|
utilizes from an X509 certificate is the key material._ This has
|
|
several implications:
|
|
|
|
* Certs are never PKI validated.
|
|
* Certification extensions that define key usage, etc. are never
|
|
checked.
|
|
* The certificate validity period is never checked, thus a cert
|
|
contained in metadata never expires as a consequence of its
|
|
certificate validity period. Instead the validity period of the
|
|
*key* is controlled by the `<md:validUntil>` or `<md:cacheDuration>`
|
|
metadata attribute associated with the key.
|
|
* Using self-signed certs used in SAML metadata is fine because the
|
|
PKI data is never evaluated.
|
|
|
|
In fact extracting the key from an `<ds:X509Certificate>` element and
|
|
placing it inside a `<ds:KeyValue>` element instead is semantically
|
|
identical. A `<ds:X509Certificate>` element is just a container for the
|
|
key, nothing more than that. Certificates are used only because they
|
|
are easy to generate and are readily available.
|
|
|
|
IMPORTANT: The consequence of the above is that a provider's metadata *is*
|
|
the trust mechanism in SAML. *_Any compromise of a provider's metadata
|
|
is a compromise of SAML security._*
|
|
|
|
IMPORTANT: Even though the keys and certs used inside SAML metadata
|
|
for signing and encryption are not PKI validated, the key and cert used
|
|
to establish a TLS secure channel between SAML entities *MUST* be
|
|
fully PKI validated using a chain all the way up to a trusted CA. Do not
|
|
confuse the purpose of the keys and certs used for the purpose of
|
|
signing and encrypting SAML data with those used to establish secure
|
|
communication: they are entirely distinct.
|
|
|
|
==== Service Provider Metadata [[sp_metadata]]
|
|
|
|
This is an example of Mellon metadata. It is the SP metadata used in
|
|
our example authentication.
|
|
|
|
[source,xml]
|
|
----
|
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
<EntityDescriptor <!--1-->
|
|
xmlns="urn:oasis:names:tc:SAML:2.0:metadata" <!--2-->
|
|
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" <!--2-->
|
|
xmlns:ds="http://www.w3.org/2000/09/xmldsig#" <!--2-->
|
|
entityID="https://mellon.example.com/mellon/metadata"> <!--3-->
|
|
<SPSSODescriptor <!--4-->
|
|
AuthnRequestsSigned="true" <!--5-->
|
|
WantAssertionsSigned="true" <!--6-->
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing"> <!--7-->
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>...</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<KeyDescriptor use="encryption"> <!--8-->
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>...</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<SingleLogoutService <!--9-->
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<SingleLogoutService <!--10-->
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat> <!--11-->
|
|
<AssertionConsumerService <!--12-->
|
|
index="0"
|
|
isDefault="true" <!--13-->
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://mellon.example.com/mellon/postResponse" />
|
|
<AssertionConsumerService <!--14-->
|
|
index="1"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
|
|
Location="https://mellon.example.com/mellon/artifactResponse" />
|
|
<AssertionConsumerService <!--15-->
|
|
index="2"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS"
|
|
Location="https://mellon.example.com/mellon/paosResponse" />
|
|
</SPSSODescriptor>
|
|
</EntityDescriptor>
|
|
----
|
|
|
|
<1> `EntityDescriptor` is a container for all properties belonging to
|
|
the entity identified by the `entityID` name. SAML metadata allows
|
|
a single metadata document to describe multiple entities. In that case
|
|
the top level element will be a `<EntitiesDescriptor>` element which
|
|
will contain one or more `<EntityDescriptor>` elements. If the
|
|
metadata describes only a single entity, it is permissible to just use
|
|
a `<EntityDescriptor>`.
|
|
|
|
<2> XML namespace declaration. This provides an abbreviated shorthand
|
|
to identify which namespace an XML element belongs to. The shorthand
|
|
name is the string preceding the equals sign. If the name is absent it
|
|
becomes the default namespace for XML elements which are not prefixed
|
|
with a namespace. Thus for example `xmlns:ds="..."` sets `ds` as
|
|
the namespace prefix for XML digital signature elements and
|
|
`<ds:KeyInfo>` means the `KenInfo` element belongs to the XML digital
|
|
signature namespace because it is prefixed with `ds:`. *There is no
|
|
prescribed list of namespace prefixes, rather the document defines the
|
|
prefix.* By convention certain prefix names are commonly used. _A
|
|
common mistake is to assume that all SAML XML documents will use the same
|
|
namespace prefixes_. This is not true and leads to misunderstandings
|
|
and/or parsing errors.
|
|
|
|
<3> [[sp_metadata_entityid]] entityID. This is the unique name of the SAML provider. It *must*
|
|
be a URI. See <<entityID>>.
|
|
|
|
<4> A provider role. In this instance the role is `SPSSODescriptor`,
|
|
which means it's a Service Provider. A provider may have multiple
|
|
roles, therefore an entity may have more than one role element. In our
|
|
example there is only one role. See <<saml_roles>>.
|
|
|
|
<5> `AuthnRequestsSigned`. If true then the SP will be sending a signed
|
|
`<AuthnRequest>` to the IdP.
|
|
|
|
<6> `WantAssertionsSigned`. If true then the SP desires the IdP to
|
|
sign its assertions. Assertions should always be signed.
|
|
|
|
<7> X509 certificate information. The `use` attribute of `signing`
|
|
identifies that this certificate will be used for signing data.
|
|
There may be multiple keys of this type, permitting key rotation.
|
|
|
|
<8> X509 certificate information. The `use` attribute of `encryption`
|
|
identifies that this certificate will be used for encrypting data.
|
|
There may be multiple keys of this type, permitting key rotation.
|
|
|
|
<9> SAML endpoint. Logout messages using a SOAP binding are sent to
|
|
this URL location.
|
|
|
|
<10> SAML endpoint. Logout messages using the HTTP-Redirect binding
|
|
are sent to this URL location.
|
|
|
|
<11> Zero or more `<NameIDFormat>` elements enumerate the name
|
|
identifier formats supported by this entity. See <<name_id>> for
|
|
details.
|
|
|
|
<12> [[sp_metadata_acs]] SAML endpoint. Assertions using the HTTP-POST binding are
|
|
delivered to this URL location.
|
|
|
|
<13> For indexed endpoints if `isDefault` is true then this is the
|
|
default endpoint to select. If no endpoint claims to be the default
|
|
then the first endpoint in the list is the default.
|
|
|
|
<14> SAML endpoint. Assertions using the HTTP-Artifact binding are
|
|
delivered to this URL location.
|
|
|
|
<15> SAML endpoint. Assertions using the PAOS binding are delivered to
|
|
this URL location. PAOS is used the the Enhanced Client or Proxy
|
|
Profile (a.k.a. ECP).
|
|
|
|
==== Identity Provider Metadata [[idp_metadata]]
|
|
|
|
This is an example of a IdP metadata as generated by a Red Hat SSO
|
|
server (Keycloak). It is the IdP metadata used in our example
|
|
authentication.
|
|
|
|
[source,xml]
|
|
----
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<EntitiesDescriptor Name="urn:keycloak" <!--1-->
|
|
xmlns="urn:oasis:names:tc:SAML:2.0:metadata" <!--2-->
|
|
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"> <!--2-->
|
|
<EntityDescriptor <!--3-->
|
|
entityID="https://rhsso.example.com:8443/auth/realms/test"> <!--4-->
|
|
<IDPSSODescriptor <!--5-->
|
|
WantAuthnRequestsSigned="true" <!--6-->
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing"> <!--7-->
|
|
<dsig:KeyInfo>
|
|
<dsig:KeyName>1VPndjfABB6S4lb4zwMLjBUhxfzPFnfrvNYvRgcxiUM</dsig:KeyName>
|
|
<dsig:X509Data>
|
|
<dsig:X509Certificate>...</dsig:X509Certificate>
|
|
</dsig:X509Data>
|
|
</dsig:KeyInfo>
|
|
</KeyDescriptor>
|
|
<SingleLogoutService <!--8-->
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/test/protocol/saml" />
|
|
<SingleLogoutService <!--9-->
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/test/protocol/saml" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat> <!--10-->
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat> <!--10-->
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</NameIDFormat> <!--10-->
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat> <!--10-->
|
|
<SingleSignOnService <!--11-->
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/test/protocol/saml" />
|
|
<SingleSignOnService <!--12-->
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/test/protocol/saml" />
|
|
<SingleSignOnService <!--13-->
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://rhsso.example.com:8443/auth/realms/test/protocol/saml" />
|
|
</IDPSSODescriptor>
|
|
</EntityDescriptor>
|
|
</EntitiesDescriptor>
|
|
----
|
|
|
|
<1> `EntitiesDescriptor` is a container for multiple
|
|
`<EntityDesciptor>` elements.
|
|
|
|
<2> XML namespace declaration. This provides an abbreviated shorthand
|
|
to identify which namespace an XML element belongs to. The shorthand
|
|
name is the string preceding the equals sign. If the name is absent it
|
|
becomes the default namespace for XML elements which are not prefixed
|
|
with a namespace. Thus for example `xmlns:ds="..."` sets `ds` as
|
|
the namespace prefix for XML digital signature elements and
|
|
`<ds:KeyInfo>` means the `KeyInfo` element belongs to the XML digital
|
|
signature namespace because it is prefixed with `ds:`. *There is no
|
|
prescribed list of namespace prefixes, rather the document defines the
|
|
prefix.* By convention certain prefix names are commonly used. _A
|
|
common mistake is to assume all SAML XML documents will use the same
|
|
namespace prefixes_. This is not true and leads to misunderstandings
|
|
and/or parsing errors.
|
|
|
|
<3> `EntityDescriptor` is a container for all properties belonging to
|
|
the entity identified by the `entityID` name.
|
|
|
|
<4> entityID. This is the unique name of the SAML provider. It *must*
|
|
be a URI. See <<entityID>>.
|
|
|
|
<5> A provider role. In this instance the role is `IDPSSODescriptor`,
|
|
which means it's an Identity Provider. A provider may have multiple
|
|
roles, therefore an entity may have more than one role element. In our
|
|
example there is only one role. See <<saml_roles>>.
|
|
|
|
<6> `WantAuthnRequestsSigned`. If true, indicates that this IdP requires
|
|
every `<AuthnRequest>` submitted by an SP to be signed.
|
|
|
|
<7> X509 certificate information. The `use` attribute of `signing`
|
|
identifies that this certificate will be used for signing data.
|
|
There may be multiple keys of this type, permitting key rotation.
|
|
|
|
<8> SAML endpoint. Logout messages using the HTTP-POST binding are
|
|
sent to this URL location.
|
|
|
|
<9> SAML endpoint. Logout messages using the HTTP-Redirect binding are
|
|
sent to this URL location.
|
|
|
|
<10> Zero or more `<NameIDFormat>` elements enumerate the name
|
|
identifier formats supported by this entity. See <<name_id>> for more
|
|
details.
|
|
|
|
<11> SAML endpoint. `<AuthnRequest>` messages using the HTTP-POST
|
|
binding are sent by the SP to this URL location to establish a Single
|
|
Sign-On Session.
|
|
|
|
<12> SAML endpoint. `<AuthnRequest>` messages using the HTTP-Redirect
|
|
binding are sent by the SP to this URL location to establish a Single
|
|
Sign-On Session.
|
|
|
|
<13> SAML endpoint. `<AuthnRequest>` messages using the SOAP
|
|
binding are sent by the SP to this URL location to establish a Single
|
|
Sign-On Session.
|
|
|
|
|
|
|
|
== Installing & Configuring Mellon
|
|
|
|
=== Installing Mellon
|
|
|
|
Mellon can be built and installed from source code located in the
|
|
https://github.com/UNINETT/mod_auth_mellon[mod_auth_mellon GitHub
|
|
repository]. However for most people the best option is to install
|
|
Mellon using a pre-built package available from the package manager on
|
|
your operating system. Pre-built packages relieve you of having to
|
|
know the intricacies of building and installing from source, track and
|
|
install security fixes, and track and apply bug fixes. Pre-built
|
|
packages also are tailored to your operating system environment, often
|
|
including OS specific configuration and support files deemed useful by
|
|
the packaging authority.
|
|
|
|
.On RHEL (CentOS)
|
|
----
|
|
sudo yum install mod_auth_mellon
|
|
----
|
|
|
|
.On Fedora
|
|
----
|
|
sudo dnf install mod_auth_mellon
|
|
----
|
|
|
|
.On Debian (Ubuntu)
|
|
----
|
|
apt-get install libapache2-mod-auth-mellon
|
|
----
|
|
|
|
.From source
|
|
----
|
|
./configure
|
|
make
|
|
sudo make install
|
|
----
|
|
|
|
NOTE: If building from source you'll need to have all the necessary
|
|
dependencies available at build time. Determining the exact set of
|
|
dependencies and where to locate them is operating system
|
|
dependent. It is assumed you have the necessary knowledge to correctly
|
|
perform the requisite operations which is out of scope for this document.
|
|
|
|
=== Mellon Configuration [[mellon_config]]
|
|
|
|
Once installed, mod_auth_mellon does not do anything until it's
|
|
configured to operate on a URL. Mellon is configured in the same way
|
|
as other Apache modules. See
|
|
http://httpd.apache.org/docs/current/configuring.html[Apache
|
|
Configuration Files].
|
|
|
|
There are two independent steps necessary to enable Mellon.
|
|
|
|
1. Load the mod_auth_mellon Apache module at Apache start-up.
|
|
2. Configure Mellon to operate on specific URLs with specific SAML
|
|
properties.
|
|
|
|
==== Load mod_auth_mellon [[load_mod_auth_mellon]]
|
|
|
|
To accomplish the first task of loading the mod_auth_mellon module
|
|
Apache needs to execute this configuration directive:
|
|
|
|
----
|
|
LoadModule auth_mellon_module modules/mod_auth_mellon.so
|
|
----
|
|
|
|
Different distributions may handle Apache module loading differently, but as
|
|
of Apache 2.4 the preferred technique is to drop a file in the
|
|
`conf.modules.d` Apache directory with the above content. Apache
|
|
automatically processes all `.conf` files in this directory at
|
|
start-up.
|
|
|
|
[NOTE]
|
|
.Red Hat Specific
|
|
====
|
|
Red Hat RPM's add the file
|
|
`/etc/httpd/conf.modules.d/10-auth_mellon.conf` with the above
|
|
`LoadModule` directive, so there is no further action needed to load
|
|
the module after the RPM is installed.
|
|
====
|
|
|
|
==== Mellon Configuration Files [[mellon_config_files]]
|
|
|
|
To accomplish the second task of configuring Mellon, Apache will need
|
|
to read Mellon configuration directives when it initializes. The
|
|
preferred mechanism is to place those directives in a file located in
|
|
the Apache `conf.d` directory, Apache will read all `.conf` files in
|
|
this directory at start-up. Although you could place the Mellon
|
|
directives in any config file, a good practice to follow is keep the
|
|
Mellon directives in their own file. See <<mellon_config_file>> for
|
|
more information.
|
|
|
|
Mellon relies on SAML specific files as well, for example:
|
|
|
|
* IdP metadata file(s)
|
|
* Mellon's SP metadata file
|
|
* Certificate and key files
|
|
|
|
Although you are free to locate these SAML specific files in the
|
|
`/etc/httpd/conf.d` Apache configuration directory, they are not
|
|
strictly speaking Apache configuration files. Many deployments choose
|
|
to locate the SAML files in a sibling directory, for example
|
|
`/etc/httpd/saml2`.
|
|
|
|
NOTE: If you are running with SELinux enabled (as you should be) you
|
|
may run into SELinux file permission problems if you locate files
|
|
Mellon reads and writes outside the standard Apache directories
|
|
because externally located files will not automatically receive the
|
|
proper SELinux labels.
|
|
|
|
=== Mellon Configuration Directives
|
|
|
|
Mellon's configuration directives are documented in Mellon's `README`
|
|
file. The README is the best place to learn and review Mellon
|
|
configuration directives because it will match the installed version
|
|
of Mellon.
|
|
|
|
[NOTE]
|
|
.Red Hat Specific
|
|
====
|
|
Red Hat RPM's install the README file in
|
|
`/usr/share/doc/mod_auth_mellon*/README`.
|
|
====
|
|
|
|
Mellon configuration directives are broken into 2 types:
|
|
|
|
* Module level (i.e. global values shared by each virtual server)
|
|
* Directory level (i.e. applied to directories and URL locations)
|
|
|
|
The README groups all module level directives together at the top of
|
|
the file, the directory level directory level directives follow. Most
|
|
users will only need to configure the directory level directives which
|
|
comprise 2 basic types and are documented in http://httpd.apache.org/docs/current/mod/core.html[Apache Core Features]:
|
|
|
|
<Directory> Directive:: Enclose a group of directives that apply only
|
|
to the named file-system directory, sub-directories, and their
|
|
contents.
|
|
|
|
<Location> Directive:: Applies the enclosed directives only to
|
|
matching URLs.
|
|
|
|
The critical thing to remember when writing and reading Mellon
|
|
configuration is that like all Apache directory level configuration it is
|
|
*_hierarchical_*. The path portion of the URL is like a file system
|
|
directory tree. If a Mellon configuration directive is not
|
|
_explicitly_ defined for a particular point in the tree, the value is
|
|
*_inherited_* from the closest ancestor that defines it. If no
|
|
ancestor defines the value then Mellon's default value is applied. The
|
|
default value for each Mellon configuration directive is listed in
|
|
Mellon's `README` file.
|
|
|
|
=== Mellon Configuration File [[mellon_config_file]]
|
|
|
|
For our demo example we will place these directives in the file
|
|
`/etc/httpd/conf.d/demo_mellon.conf`. Let's briefly review what the
|
|
demo configuration is meant to accomplish and illustrate:
|
|
|
|
* We are protecting with SAML authentication the URL location
|
|
`https://mellon.example.com/private` and everything below it in URL
|
|
space.
|
|
|
|
* To eliminate redundant cut-n-paste of shared SAML directives in each
|
|
protected location we gather the common Mellon directives in a
|
|
location _above_ any of the protected locations in the URL
|
|
tree. This permits all protected locations to hierarchically inherit
|
|
the same values from a common single set of directives.
|
|
|
|
----
|
|
<Location /> <1>
|
|
MellonEnable info <2>
|
|
MellonEndpointPath /mellon/ <3>
|
|
MellonSPMetadataFile /etc/httpd/saml2/demo_sp_metadata.xml <4>
|
|
MellonSPPrivateKeyFile /etc/httpd/saml2/demo.key <5>
|
|
MellonSPCertFile /etc/httpd/saml2/demo.cert <6>
|
|
MellonIdPMetadataFile /etc/httpd/saml2/demo_keycloak_test_idp_metadata.xml <7>
|
|
</Location>
|
|
|
|
<Location /private> <8>
|
|
AuthType Mellon <9>
|
|
MellonEnable auth <10>
|
|
Require valid-user <11>
|
|
</Location>
|
|
|
|
----
|
|
|
|
<1> The first `Location` directive on the `/` _root_ is simply a
|
|
convenient place to locate common configuration directives that will
|
|
be shared by all Mellon protected locations. In this instance it
|
|
defines the metadata files and certificates and keys. It is not
|
|
necessary to locate this on the `/` _root_ URL, in fact in a real
|
|
world deployment you probably will want to locate the common shared
|
|
set of Mellon directives lower in the hierarchy. The only requirement
|
|
is that _all_ of the protected locations are positioned below it so they may
|
|
inherit those values. footnote:[When you are protecting just one
|
|
location with Mellon there isn't much added value in splitting the
|
|
configuration directives. But when you need to protect many distinct
|
|
locations, it's repetitive and error prone to cut and paste common
|
|
values in each `<Location>` block. It makes maintaining the
|
|
configuration that much more difficult because you will need to edit
|
|
each and every `<Location>` directive to change something like the
|
|
name of a metadata file. This is why Mellon configuration often groups
|
|
common values in a location that can be shared by all
|
|
descendants. Using the `/` _root_ location is the most obvious example
|
|
but the same idea can be applied to complex trees.]
|
|
|
|
<2> Mellon does not process any directives unless it's enabled for
|
|
that location either explicitly or via inheritance. See
|
|
<<mellon_modes>> for more details.
|
|
|
|
<3> Defines where the Mellon endpoints are located in URL space. This
|
|
is a *critical* value to properly specify and is one of the *_most
|
|
common Mellon configuration errors_* leading to a failed deployment.
|
|
Please refer to <<mellon_endpoint_path,MellonEndpointPath>> to
|
|
understand its requirements and what it influences. Also see
|
|
<<incorrect_mellon_endpoint_path>> for a discussion of this common
|
|
error. The important thing to note in this example is the
|
|
`MellonEndpointPath` is located *inside* the containing location
|
|
directive of `/` (e.g. a child).
|
|
|
|
<4> The SAML metadata for this provider (i.e. Mellon's metadata). This
|
|
metadata plays 2 important roles: Mellon reads it at start-up to
|
|
initialize itself, and you provide the IdP specified in
|
|
`MellonIdPMetadataFile` with this metadata. Both Mellon (the SP) and
|
|
your IdP *MUST* have loaded exactly the same Mellon metadata in other
|
|
to interoperate. Out of sync metadata is a very common deployment
|
|
error. See <<metadata_creation, Metadata Creation>> for how Mellon
|
|
metadata is created. `MellonSPMetadataFile` is optional, Mellon can
|
|
create its own metadata from its initial configuration parameters.
|
|
|
|
<5> The private cryptographic key used by Mellon to sign its SAML
|
|
data. See <<metadata_keys>> for more detail.
|
|
|
|
<6> The public cryptographic key associated with the private key. This
|
|
public key is embedded in Mellon's metadata so that an IdP can
|
|
validate Mellon's signed data. See <<metadata_keys>> for more detail.
|
|
|
|
<7> The IdP used to authenticate is specified by its metadata
|
|
file. See <<obtain_idp_metadata>> for how to obtain this data.
|
|
|
|
<8> This is a URL location protected by Mellon. For our example we've
|
|
used the `/private` URL. Note that this `<Location>` block is simple and
|
|
does not contain many of the necessary Mellon directives, because those other
|
|
Mellon directives are inherited from an ancestor location, in our
|
|
example `/`. The only Mellon directives in this location block are
|
|
those necessary to turn on Mellon authentication. This configuration
|
|
strategy permits you to define many subordinate protected locations all
|
|
sharing the same common Mellon directives via inheritance.
|
|
|
|
<9> `AuthType` is an Apache directive specifying which Apache
|
|
authentication module will perform the authentication for this
|
|
location. Obviously we want to use Mellon.
|
|
|
|
<10> Instruct Mellon that this location (and all its descendants) will be
|
|
authenticated. See <<mellon_modes>>.
|
|
|
|
<11> `Require` is an Apache directive that instructs Apache's
|
|
authentication and authorization sub-system that it must successfully
|
|
authenticate the user.
|
|
|
|
==== Load Your SP metadata into the IdP [[load_sp_metadata_into_idp]]
|
|
|
|
After you have created your SP metadata as described in
|
|
<<metadata_creation, Metadata Creation>>, you must load your metadata
|
|
into the IdP referenced in your `MellonIdPMetadataFile`. How to
|
|
perform the SP metadata load is specific to the IdP you're using and
|
|
you will need to consult your IdP documentation to learn the procedure.
|
|
|
|
WARNING: If you subsequently modify your SP metadata you *MUST* reload
|
|
it into the IdP. Both your metadata and the IdP metadata must be in
|
|
sync at all times. Failure to reload any modified metadata is a recipe
|
|
for problems.
|
|
|
|
==== Obtaining IdP Metadata [[obtain_idp_metadata]]
|
|
|
|
In order to Mellon to communicate with and interoperate with an IdP it
|
|
must have the IdP's metadata. You may want to refer to <<metadata>> for
|
|
a more comprehensive description. But how do you obtain the metadata
|
|
belonging to the IdP? There is no fixed rule on how this is
|
|
accomplished. You will have to refer to your IdP's documentation. It
|
|
may be published at a well known location (e.g. a URL) for download or
|
|
there may be some other publication mechanism.
|
|
|
|
IMPORTANT: SAML provider metadata is extremely security sensitive, it
|
|
contains the cryptographic keys used to secure SAML. If you download
|
|
metadata from a URL do so only over a secure channel such as https and
|
|
make sure the download operation properly validates the server cert up
|
|
to a CA you trust. _Do not trust a server offering a self-signed
|
|
cert_. If the obtained metadata is signed you *MUST* validate the
|
|
signature on the metadata.
|
|
|
|
=== Mellon Modes [[mellon_modes]]
|
|
|
|
For any given location Mellon can be in one of 3 modes defined by the
|
|
`MellonEnable` directive:
|
|
|
|
off::
|
|
Mellon will not do anything in this location.
|
|
This is the default state.
|
|
|
|
info::
|
|
If the user is authorized to access the resource, then
|
|
Mellon will populate the environment with information about
|
|
the user. If the user isn't authorized, then Mellon won't
|
|
populate the environment, but Mellon won't deny the user
|
|
access either.
|
|
|
|
auth::
|
|
Mellon will populate the environment with information about
|
|
the user if he is authorized. If he is authenticated
|
|
(logged in), but not authorized (according to the
|
|
`MellonRequire` and `MellonCond` directives, then Mellon will
|
|
return a 403 Forbidden error. If he isn't authenticated
|
|
then Mellon will redirect to the login page of the configured IdP.
|
|
|
|
The most common situation is to protect a specific location with
|
|
Mellon authentication. This requires at a minimum these 3 directives:
|
|
|
|
----
|
|
AuthType Mellon <1>
|
|
MellonEnable auth <2>
|
|
Require valid-user <3>
|
|
----
|
|
|
|
<1> This is an Apache directive that says authentication is to be
|
|
performed with Mellon as opposed to another Apache authentication
|
|
module.
|
|
|
|
<2> This informs Mellon it is to perform authentication as described
|
|
above.
|
|
|
|
<3> This is an Apache directive that says an authentication module
|
|
must have successfully authenticated a user in order to proceed.
|
|
|
|
=== How is Mellon metadata created? [[metadata_creation]]
|
|
|
|
The purpose of SAML metadata is describe in <<metadata>>. An annotated
|
|
example of Mellon metadata is presented in <<sp_metadata>>. There are
|
|
multiple ways one can create Mellon metadata:
|
|
|
|
. Use the `mellon_create_metadata.sh` script. The mod_auth_mellon RPM
|
|
installs this script in
|
|
`/usr/libexec/mod_auth_mellon/mellon_create_metadata.sh`.
|
|
|
|
. Allow Mellon to dynamically generate its metadata based on its
|
|
configuration options. The metadata can be downloaded from the
|
|
`$MellonEndpointPath/metadata` URL. Mellon only self-generates its
|
|
metadata if the `MellonSPMetadataFile` configuration parameter is not
|
|
defined, otherwise if the `MellonSPMetadataFile` is defined the
|
|
`$MellonEndpointPath/metadata` download URL will return the contents
|
|
of the `MellonSPMetadataFile`.
|
|
|
|
. Use a third-party tool such as `keycloak-http-client-install`.
|
|
|
|
. Write it from scratch. (Not kidding, many provider administrators
|
|
hand create and hand edit their metadata).
|
|
|
|
IMPORTANT: Before proceeding further with Mellon metadata it is
|
|
essential you understand the <<MellonEndpointPath>>.
|
|
|
|
==== Using `mellon_create_metadata.sh` [[using_mellon_create_metadata_sh]]
|
|
|
|
`mellon_create_metadata.sh` requires two positional parameters
|
|
|
|
* <<entityID,entityID>>
|
|
* endpoint_url
|
|
|
|
The entityID is the unique name of the Mellon SP. The entityID plays
|
|
an important role in SAML and you may wish to review its description
|
|
in <<entityID>>.
|
|
|
|
The endpoint_url is the concatenation of the `https` scheme, the Mellon
|
|
hostname, and the <<mellon_endpoint_path,MellonEndpointPath>>.
|
|
|
|
Using our example data the entityID will be
|
|
`https://mellon.example.com/mellon/metadata` and the endpoint_url will
|
|
be `https://mellon.example.com/mellon`
|
|
|
|
----
|
|
$ /usr/libexec/mod_auth_mellon/mellon_create_metadata.sh "https://mellon.example.com/mellon/metadata" "https://mellon.example.com/mellon"
|
|
Output files:
|
|
Private key: https_mellon.example.com_mellon_metadata.key
|
|
Certificate: https_mellon.example.com_mellon_metadata.cert
|
|
Metadata: https_mellon.example.com_mellon_metadata.xml
|
|
Host: mellon.example.com
|
|
|
|
Endpoints:
|
|
SingleLogoutService (SOAP): https://mellon.example.com/mellon/logout
|
|
SingleLogoutService (HTTP-Redirect): https://mellon.example.com/mellon/logout
|
|
AssertionConsumerService (HTTP-POST): https://mellon.example.com/mellon/postResponse
|
|
AssertionConsumerService (HTTP-Artifact): https://mellon.example.com/mellon/artifactResponse
|
|
AssertionConsumerService (PAOS): https://mellon.example.com/mellon/paosResponse
|
|
----
|
|
|
|
The script produces 3 files containing the cert, key, and metadata, all
|
|
prefixed with the entityID. In this example it would be:
|
|
|
|
* https_mellon.example.com_mellon_metadata.cert
|
|
* https_mellon.example.com_mellon_metadata.key
|
|
* https_mellon.example.com_mellon_metadata.xml
|
|
|
|
You will need to move these files into the Apache configuration
|
|
directory and possibly rename them to something more sensible. You will refer to
|
|
these files inside the Mellon
|
|
configuration as these Mellon directives:
|
|
|
|
* `MellonSPPrivateKeyFile`
|
|
* `MellonSPCertFile`
|
|
* `MellonSPMetadataFile`
|
|
|
|
==== Using Mellon to generate its own metadata [[using_mellon_to_create_metadata]]
|
|
|
|
Mellon has the built-in capability to generate its own metadata as
|
|
long as you provide a few necessary Mellon configuration directives.
|
|
|
|
* `MellonSPentityId`
|
|
* `MellonSPPrivateKeyFile`
|
|
* `MellonSPCertFile`
|
|
* `MellonEndpointPath` (not mandatory if you use the default)
|
|
|
|
When Mellon initializes it will check the value of the
|
|
`MellonSPMetadataFile`. If it does not exist Mellon will generate
|
|
its own metadata. If `MellonSPMetadataFile` exists, that metadata will
|
|
always be used. If Mellon generates its own metadata it does not
|
|
write the metadata back to a file, rather it's held in memory.
|
|
|
|
Irrespective of whether Mellon self generates its metadata or if it
|
|
loads it from a file specified by `MellonSPMetadataFile`, the metadata
|
|
is made available for download at the `$MellonEndpointPath/metadata`
|
|
URL. You can perform a GET on this URL to capture the SP metadata and
|
|
save it in a file. It is recommended you do this as an initial
|
|
configuration set-up step and then always subsequently load the
|
|
metadata via the `MellonSPMetadataFile` directive. The rationale for
|
|
this is you want to be sure you know what metadata Mellon is
|
|
initializing with and that it identically matches what you've loaded
|
|
into the IdP. You may also wish to customize your SP metadata by
|
|
making edits to it.
|
|
|
|
==== Where do the keys and certs come from?
|
|
|
|
Please refer to the <<metadata_keys>> section to understand how keys
|
|
and certs are utilized inside SAML (TLS connections used for SAML
|
|
communication is an entirely different matter and it is mandated keys
|
|
and certs used for TLS be PKI validated). The main point to
|
|
understand is that even though most SAML implementations use x509 utilities
|
|
to generate certs and keys, SAML's use of them does not involve PKI.
|
|
Only the key material is used. The consequence of this is it's
|
|
okay to generate self-signed certs for use inside a provider's metadata
|
|
because they are not PKI validated. Many of the metadata creation
|
|
tools generate a self-signed cert for use in the metadata. However it
|
|
is perfectly fine to use your own key and cert instead of one
|
|
generated by an installation tool. You can accomplish this with Mellon
|
|
by pointing the `MellonSPPrivateKeyFile` and `MellonSPCertFile`
|
|
directives at your own key and cert files and then downloading the SP
|
|
metadata as described in <<using_mellon_to_create_metadata>>.
|
|
|
|
==== Signing metadata [[sign_metadata]]
|
|
|
|
SAML requires provider metadata to be integrity protected. Publishing
|
|
provider metadata over a secure TLS channel goes a long way to
|
|
accomplishing this goal and may be considered sufficient depending on
|
|
the security requirements. SAML metadata can be integrity protected by
|
|
signing the metadata with an XML signature. Some providers may require
|
|
any metadata they consume be signed. Unfortunately neither Mellon nor
|
|
any of the tools currently associated with Mellon have support for
|
|
signing Mellon metadata. Fortunately there are a variety of tools
|
|
available to sign an XML document and since SAML metadata is a normal
|
|
XML document any of these tools can be used to sign the Mellon
|
|
metadata.
|
|
|
|
===== Using xmlsec to sign metadata [[xmlsec_metadata_signing]]
|
|
|
|
The `xmlsec` tools are commonly available on most Linux based
|
|
system. In fact the `Lasso` library which supplies Mellon with its
|
|
SAML implementation uses the `xmlsec` library to perform all of its
|
|
XML signing and signature verification. `xmlsec` usually ships with an
|
|
`xmlsec` command line utility, which can perform XML signing
|
|
and verification from the command line.
|
|
|
|
NOTE: `xmlsec` may be packaged under the name `xmlsec1` in your
|
|
distribution. This is the case for all Red Hat distributions.
|
|
|
|
To sign Mellon metadata using `xmlsec` you need to add a signature
|
|
template to the Mellon metadata. When `xmlsec` reads the input
|
|
metadata it locates the empty signature template and replaces it with
|
|
a processed signature. The signature template should be placed near
|
|
the top of the metadata, ideally just after the `<EntityDescriptor>`
|
|
element. Here is an example of a signature template:
|
|
|
|
[source,xml]
|
|
----
|
|
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
|
<SignedInfo>
|
|
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n"/>
|
|
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
|
<Reference URI="">
|
|
<Transforms>
|
|
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
|
|
</Transforms>
|
|
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
|
<DigestValue></DigestValue>
|
|
</Reference>
|
|
</SignedInfo>
|
|
<SignatureValue />
|
|
<KeyInfo>
|
|
<KeyValue />
|
|
</KeyInfo>
|
|
</Signature>
|
|
----
|
|
|
|
Because the `<Reference> URI` attribute is the empty string the entire
|
|
document will be signed. In order for `xmlsec` to generate a signature
|
|
you will need to supply it with both the private and public key parts.
|
|
|
|
----
|
|
xmlsec \\ <1>
|
|
--sign \\ <2>
|
|
--privkey-pem demo.key \\ <3>
|
|
--pubkey-cert-pem demo.cert \\ <4>
|
|
--output signed_metadata.xml \\ <5>
|
|
metadata.xml <6>
|
|
----
|
|
|
|
<1> `xmlsec` command may be named `xmlsec1` on your system
|
|
<2> Perform signing
|
|
<3> Private key used for signing
|
|
<4> Public key used to verify signature (included in signature)
|
|
<5> Output file containing signed metadata
|
|
<6> Input unsigned metadata (with signature template)
|
|
|
|
To verify the signature on the command line:
|
|
|
|
----
|
|
xmlsec \\ <1>
|
|
--verify \\ <2>
|
|
signed_metadata.xml <3>
|
|
----
|
|
|
|
<1> `xmlsec` command may be named `xmlsec1` on your system
|
|
<2> Perform verification
|
|
<3> Input signed metadata
|
|
|
|
=== MellonEndpointPath [[mellon_endpoint_path]]
|
|
|
|
Mellon reserves a number of URLs for its use. Some of these
|
|
URLs are the public SAML <<endpoints, endpoints>> advertised in the
|
|
<<sp_metadata, SP metadata>>. Others are for Mellon's private use.
|
|
The best way to think of these Mellon endpoints is as a way of binding a
|
|
URL to a handler. When an HTTP request arrives at one of these Mellon
|
|
endpoints a dedicated handler processes the request.
|
|
|
|
The way Mellon identifies a URL as being one of its endpoints is by
|
|
looking at the beginning of the URL path. If everything in the path
|
|
except the last path component matches the `MellonEndpointPath` then
|
|
Mellon recognizes the URL as being one of its endpoints. The last
|
|
path component is used to bind to the handler.
|
|
|
|
Let's use an example. If the `MellonEndpointPath` is `/foo/bar` then
|
|
any URL with the form `/foo/bar/xxx` will be handled by Mellon's xxx
|
|
handler.
|
|
|
|
Mellon enforces 2 strict requirements on the `MellonEndpointPath`:
|
|
|
|
* The path *must* be an absolute path from the root of the web server.
|
|
|
|
* The path *must* be a sub-path of the Mellon `<Location>`
|
|
directive that defines it. The reason for this is simple. Mellon
|
|
ignores locations which are not configured for Mellon. Therefore for
|
|
Mellon to respond to a request on one of its SAML endpoints, the
|
|
endpoint has to be inside a path that Mellon is watching.
|
|
|
|
=== Mellon Endpoints [[mellon_endpoints]]
|
|
|
|
Mellon endpoints are hung off of the <<mellon_endpoint_path>>.
|
|
Mellon reserves a number of URLs for its use. Some of these
|
|
URLs are the public SAML <<endpoints, endpoints>> advertised in the
|
|
<<sp_metadata, SP metadata>>. Others are for Mellon's private use.
|
|
The best way to think of these Mellon endpoints is a way of binding a
|
|
URL to a handler. When an HTTP request arrives at one of these Mellon
|
|
endpoints a dedicated handler processes the request.
|
|
|
|
The current list of Mellon endpoints (handlers) is:
|
|
|
|
postResponse::
|
|
The _AssertionConsumerService_ endpoint using the SAML HTTP-POST
|
|
binding.
|
|
|
|
artifactResponse::
|
|
The _AssertionConsumerService_ endpoint for SAML artifacts. SAML artifacts
|
|
provide an indirect method to convey data. An artifact is an
|
|
identifier that points to data. Requesting data using the artifact
|
|
identifier returns the associated data.
|
|
|
|
paosResponse::
|
|
The AssertionConsumerService endpoint using the SAML PAOS
|
|
binding.
|
|
|
|
login::
|
|
Mellon internal endpoint used to start the authentication process with
|
|
an IdP. Any request whose URL needs authentication is redirected here
|
|
to start the login process.
|
|
|
|
logout::
|
|
The SingleLogoutService SAML endpoint.
|
|
|
|
metadata::
|
|
A HTTP GET request on this endpoint will return the SP's metadata.
|
|
|
|
repost::
|
|
Mellon internal endpoint which replays POST data from the original
|
|
request.
|
|
|
|
auth::
|
|
Mellon internal endpoint retained for backwards compatibility.
|
|
|
|
probeDisco::
|
|
IdP probe discovery service endpoint. See "Probe IdP discover" in the
|
|
Mellon README for more information.
|
|
|
|
=== Mellon Session [[mellon_session]]
|
|
|
|
SAML sessions are described in <<saml_sessions>>.
|
|
|
|
For each successfully authenticated user Mellon maintains a
|
|
session. Mellon allocates a unique ID for the session when it is
|
|
created. The Mellon session ID is sent to the user's browser in a
|
|
<<mellon_cookie>>. The <<mellon_cookie>> is sent back to Mellon in
|
|
every request the browser makes to the SP. Mellon uses the session ID
|
|
to look-up the session data for the user. Internally Mellon calls
|
|
session data _cache data_ (this is subject to change).
|
|
|
|
At the time of this writing Mellon session data is local to one Apache
|
|
server (which may have multiple worker processes sharing data in
|
|
shared memory). This has consequences for High Availability (e.g. HA)
|
|
deployments which may be running multiple Apache servers on different
|
|
nodes behind a load balancer, see <<load_balancer_persistence>> for
|
|
detailed information on this issue.
|
|
|
|
Mellon limits the duration of a valid session by the length of time
|
|
defined in the `MellonSessionLength` directive. Currently the default
|
|
is 86400 seconds which is 24 hours.
|
|
|
|
The IdP can inform the SP how long it wishes a SP session to be valid
|
|
by passing the `SessionNotOnOrAfter` attribute in a
|
|
`<AuthnStatement>`. Mellon respects the `SessionNotOnOrAfter`
|
|
attribute and will limit its session duration based on it. Thus the
|
|
validity period for a Mellon session is the lesser of the
|
|
`MellonSessionLength` or the optional IdP `SessionNotOnOrAfter`
|
|
attribute if the IdP supplied it.
|
|
|
|
|
|
|
|
=== Mellon Cookie [[mellon_cookie]]
|
|
|
|
<<mellon_session>> information is communicated via a cookie. The
|
|
cookie name defaults to `mellon-cookie` but may be changed via the
|
|
Mellon directive `MellonVariable`. Mellon always forms the cookie name
|
|
by appending the value of `MellonVariable` to the string `mellon-` to
|
|
prevent name collisions. Thus the actual default value of
|
|
`MellonVariable` is `cookie`.
|
|
|
|
When Mellon first begins the authentication process it sets the mellon
|
|
cookie value to `cookietest`. The primary purpose of the `cookietest`
|
|
value is to confirm cookies are properly returned by the browser,
|
|
Mellon will not work correctly unless cookies are enabled. The
|
|
`cookietest` value also serves as a temporary value
|
|
indicating an authentication flow is in progress but has not yet
|
|
completed.
|
|
|
|
After Mellon successfully authenticates a user it establishes a
|
|
session for the user and generates a unique session ID which it sets
|
|
as the value of the Mellon cookie. When Mellon receives a request for
|
|
a protected resource it looks for the Mellon cookie in the HTTP
|
|
request headers. Mellon then uses the Mellon cookie value as a session
|
|
ID and attempts to look-up that session using that ID. If the session
|
|
is found and it remains valid, Mellon immediately grants access. A
|
|
Mellon session will expire, see <<mellon_session>> for information
|
|
concerning session lifetime.
|
|
|
|
== Working with SAML attributes and exporting values to web apps
|
|
|
|
When you receive a SAML assertion authenticating a subject, the
|
|
assertion will likely include additional attributes provided by the
|
|
IdP concerning the subject. Examples include the user's email address
|
|
or the groups they are a member of. You may wish to review the
|
|
<<assertion_response,assertion example>> and look for
|
|
`<saml:Attribute>` and `<saml:AttributeValue>` elements to see how the
|
|
IdP communicates these attributes. There is no fixed set of attributes
|
|
returned by an IdP, it is entirely IdP dependent. You will either have
|
|
to review your IdP's documentation or examine a returned assertion to
|
|
determine the possible attributes. See <<inspect_saml_messages>> for the
|
|
various ways you can examine the contents of a returned assertion.
|
|
|
|
Mellon communicates its results via Apache environment variables. For
|
|
every attribute received in the assertion Mellon will insert an Apache
|
|
environment variable. You have some flexibility on how Mellon adds
|
|
these environment variables which derive from the assertion
|
|
attributes.
|
|
|
|
* Attributes can be multi-valued. `MellonMergeEnvVars` controls
|
|
whether each value is added to the environment by appending an index
|
|
to the attribute name or whether the values are listed together
|
|
under the bare attribute name with each value separated by a
|
|
separator character. See <<multiple_attribute_values>>.
|
|
|
|
* Attribute names can be mapped from the name as it appears in the
|
|
assertion to a name of your choosing when it is placed in the Apache
|
|
environment. This is controlled by `MellonSetEnv` and
|
|
`MellonSetEnvNoPrefix` directives. The distinction
|
|
is `MellonSetEnv` always prepends a prefix to the
|
|
environment variable name to help to prevent name collisions. The
|
|
prefix defaults to `MELLON_` and can be configured using the
|
|
`MellonEnvPrefix` configuration option. The
|
|
`MellonSetEnvNoPrefix` directive also remaps the assertion name to a
|
|
name of your choosing but it omits prepending the environment
|
|
variable name with the prefix. See <<map_assertion_attr_name>>
|
|
|
|
Using the <<assertion_response,assertion example>> Mellon places these
|
|
environment variables in the Apache environment. See
|
|
<<multiple_attribute_values>> for an explanation of
|
|
`MellonMergeEnvVars` and its effect.
|
|
|
|
.MellonMergeEnvVars Off
|
|
----
|
|
MELLON_NAME_ID: G-803528aa-2f9e-454b-a89c-55ee74e75d1e
|
|
MELLON_NAME_ID_0: G-803528aa-2f9e-454b-a89c-55ee74e75d1e
|
|
MELLON_groups: ipausers
|
|
MELLON_groups_0: ipausers
|
|
MELLON_groups_1: openstack-users
|
|
MELLON_email: jdoe@music.com
|
|
MELLON_email_0: jdoe@music.com
|
|
MELLON_display_name: John Doe
|
|
MELLON_display_name_0: John Doe
|
|
MELLON_initials: JD
|
|
MELLON_initials_0: JD
|
|
MELLON_last_name: Doe
|
|
MELLON_last_name_0: Doe
|
|
MELLON_first_name: John
|
|
MELLON_first_name_0: John
|
|
MELLON_Role: uma_authorization
|
|
MELLON_Role_0: uma_authorization
|
|
MELLON_Role_1: manage-account
|
|
MELLON_Role_2: view-profile
|
|
MELLON_IDP: https://rhsso.example.com:8443/auth/realms/test
|
|
MELLON_IDP_0: https://rhsso.example.com:8443/auth/realms/test
|
|
----
|
|
|
|
=== Handling multiple attribute values [[multiple_attribute_values]]
|
|
|
|
If an attribute has multiple values, then they will be stored as
|
|
|
|
----
|
|
MELLON_<name>_0 value0
|
|
MELLON_<name>_1 value1
|
|
MELLON_<name>_2 value2
|
|
...
|
|
----
|
|
|
|
Since Mellon doesn't know which attributes may have multiple values,
|
|
it will store each attribute at least twice. For example:
|
|
|
|
----
|
|
MELLON_<name> value0
|
|
MELLON_<name>_0 value0
|
|
----
|
|
|
|
In the case of multivalued attributes `MELLON_<name>` will contain the
|
|
first value.
|
|
|
|
If `MellonMergeEnvVars` is enabled multiple values of attributes will
|
|
be stored in a single environment variable separated by the
|
|
`MellonMergeEnvVars` separator which defaults to the semicolon. You
|
|
can override the default separator by supplying it as the second
|
|
option to the `MellonMergeEnvVars` directive.
|
|
|
|
Thus the above environment variable list would be this if
|
|
`MellonMergeEnvVars` was on and the separator was set to the semicolon.
|
|
|
|
.MellonMergeEnvVars On ;
|
|
----
|
|
MELLON_NAME_ID: G-803528aa-2f9e-454b-a89c-55ee74e75d1e
|
|
MELLON_groups: ipausers;openstack-users
|
|
MELLON_email: jdoe@music.com
|
|
MELLON_display_name: John Doe
|
|
MELLON_initials: JD
|
|
MELLON_last_name: Doe
|
|
MELLON_first_name: John
|
|
MELLON_Role: uma_authorization;manage-account;view-profile
|
|
MELLON_IDP: https://rhsso.example.com:8443/auth/realms/test
|
|
----
|
|
|
|
=== Map assertion attribute name to different Apache environment variable name [[map_assertion_attr_name]]
|
|
|
|
Sometimes the web app is expecting a specific name for a SAML
|
|
attribute but your IdP has sent that attribute under a different
|
|
name. You can rename any assertion attribute using the `MellonSetEnv`
|
|
and `MellonSetEnvNoPrefix` directives. These allow you to rename an
|
|
assertion attribute to a name of your choosing. The `MellonSetEnv`
|
|
directive follows the same convention as all other assertion
|
|
attributes added by Mellon in that it always prefixes the environment
|
|
variable name with a configurable prefix, which defaults to `MELLON_` to help avoid name collisions in the
|
|
Apache environment. However sometimes you do not want the `MELLON_`
|
|
prefix added. In case you simply want the variables prefixed with
|
|
a different string, use the `MellonEnvPrefix` configuration option. If,
|
|
instead you want to use exactly the environment variable name as specified.,
|
|
`MellonSetEnvNoPrefix` serves this role.
|
|
|
|
To illustrate let's look at an example. Suppose your web app is
|
|
expecting an attribute which is the user's last name, specifically it
|
|
wants this attribute to be called `REMOTE_USER_LASTNAME`. However your
|
|
IdP sends this attribute as `sn`. `sn` is typically used in LDAP
|
|
directories as an attribute name for surname, or equivalently the
|
|
user's last name. To map the `sn` assertion attribute name to the
|
|
Apache environment variable name of `REMOTE_USER_LASTNAME` you would
|
|
do this:
|
|
|
|
----
|
|
MellonSetEnvNoPrefix REMOTE_USER_LASTNAME sn
|
|
----
|
|
|
|
Also see <<set_remote_user>> for an example of setting the `REMOTE_USER`
|
|
environment variable using `MellonSetEnvNoPrefix`.
|
|
|
|
The `MellonEnvPrefix` variable might be useful e.g. if you
|
|
are migrating from a different SP which used its own prefix
|
|
for the variables passed by the IdP. For example, to prefix
|
|
all variables with `NOLLEM_` you would use:
|
|
|
|
----
|
|
MellonEnvPrefix NOLLEM_
|
|
----
|
|
|
|
If you recieved an attribute-map.xml from your IDP that uses the
|
|
`urn:mace:shibboleth:2.0:attribute-map` namespace, it can be converted
|
|
to `MellonSetEnvNoPrefix` entries with `docs/mellon-attribute-map.xsl`
|
|
and loaded into your webserver configuration.
|
|
|
|
=== Using Mellon to apply constraints [[assertion_constraints]]
|
|
|
|
SAML attributes can be used for more than exporting those values to a
|
|
web app. You can also utilize SAML attributes to control whether
|
|
Mellon authentication succeeds (a form of authorization). So even
|
|
though the IdP may have successfully authenticated the user you can
|
|
apply additional constraints via the `MellonCond` directive. The basic
|
|
idea is that each `MellonCond` directive specifies one condition that
|
|
either evaluates to `True` or `False`. Multiple conditions can be
|
|
joined by logical operators. You can also specify case insensitive
|
|
matching, substring matching, regular expression matching, substitute
|
|
values, and use regular expression back references. All `MellonCond`
|
|
conditions must evaluate to `True` for the condition check to succeed
|
|
(logical conjunction) unless you use the `OR` option flag.
|
|
|
|
The directive is specified as:
|
|
|
|
----
|
|
MellonCond attr_name value [options]
|
|
----
|
|
|
|
The 1st `attr_name` parameter is the name of the SAML assertion
|
|
attribute the condition applies to. If an attribute with this name is
|
|
found, its value is retrieved and becomes the data the condition is
|
|
evaluated against. If `attr_name` is not found, the condition evaluates
|
|
to `False`.
|
|
|
|
The 2nd value parameter is the value applied to the attribute
|
|
value. For example when matching is performed the `value` parameter is
|
|
searched for inside the attribute's value.
|
|
|
|
The `value` parameter may contain format specifiers which are
|
|
substituted prior to performing an operation on the value. Format
|
|
specifiers always begin with the `%` character. Here are the valid
|
|
format specifiers:
|
|
|
|
%n:: Regular expression backreference. Regular expressions may
|
|
contain multiple sub-matches (often referred to as a regular
|
|
expression group). To refer to a specific sub-match in the regular
|
|
expression pattern use a digit between 0 and 9 as `%n`. This only
|
|
works if a prior condition had specified the [`REG,REF]` flags,
|
|
otherwise there would be no backreference to refer to.
|
|
|
|
%\{num}:: Same as `%n`, but permits a number greater than 9.
|
|
|
|
%\{ENV:x}:: Substitute the Apache environment variable `x`. If the
|
|
environment variable does not exist substitute the empty string
|
|
instead.
|
|
|
|
%%:: Quote a `%` to prevent it from being interpreted as a the
|
|
beginning of a format specifier.
|
|
|
|
|
|
The 3rd `[options]` parameter is optional and if specified is a comma
|
|
separated list of option flags enclosed in square brackets. The set of
|
|
option flags includes:
|
|
|
|
OR:: If this MellonCond evaluated to false, then the next one will be
|
|
checked. If it evaluates to true, then the overall check succeeds.
|
|
|
|
NOT:: Invert the result of the condition check. If the condition
|
|
evaluated to `True` it becomes `False`, likewise if the condition
|
|
evaluated to `False` it become `True`.
|
|
|
|
NC:: Case insensitive matching. Ignore case differences when
|
|
performing any match operation.
|
|
|
|
SUB:: Substring match. If value is included anywhere in the attribute
|
|
value as a substring the condition evaluates to `True`, otherwise
|
|
`False`. If `SUB` is not specified then the condition value and
|
|
attribute value must match in its entirety.
|
|
|
|
REG:: Regular expression match. The value is interpreted as a regular
|
|
expression. If the regular expression is found in the attribute value
|
|
the condition evaluates to `True`, `False` otherwise.
|
|
|
|
REF:: Used with REG, track regular expression back references,
|
|
So that they can be substituted in an upcoming
|
|
`MellonCond` directive.
|
|
|
|
MAP:: Use mapped name. Instead of looking up the attribute name in the
|
|
set of attributes returned in the assertion use the mapped name
|
|
specified by either `MellonSetEnv` or `MellonSetEnvNoPrefix` instead.
|
|
If the mapped name is not found then fallback to using the name in the
|
|
assertion's set of attributes.
|
|
|
|
Here is a simple example illustrating how one might utilize
|
|
`MellonCond`. Suppose we only want to allow members of the group
|
|
`openstack-users` to have access. Our IdP has provided us with the
|
|
list of groups the user is a member of in the `groups` SAML
|
|
attribute. We need to instruct Mellon to only accept an assertion if
|
|
`openstack-users` appears as one of the `groups` attribute
|
|
values. This can be accomplished like this:
|
|
|
|
----
|
|
MellonCond groups openstack-users
|
|
----
|
|
|
|
If `openstack-users` does not appear in the as one of the `groups`
|
|
attribute values the check will fail. The check will also fail if the
|
|
`groups` attribute is not defined in the assertion.
|
|
|
|
=== How to set REMOTE_USER [[set_remote_user]]
|
|
|
|
Mellon stores the authenticated user's name in the attribute `NAME_ID`
|
|
(see <<name_id>>). If you want to export the username as
|
|
`REMOTE_USER` so your web app can process this very common CGI
|
|
variable this can easily be accomplished with `MellonSetEnvNoPrefix`
|
|
like this:
|
|
|
|
----
|
|
MellonSetEnvNoPrefix REMOTE_USER NAME_ID
|
|
----
|
|
|
|
== Deployment Considerations [[deployment_considerations]]
|
|
|
|
=== Apache Servername [[apache_servername]]
|
|
|
|
When Mellon is running behind a load balancer, SSL terminator, or in a
|
|
Apache virtual host there is the opportunity for Mellon to identify
|
|
itself incorrectly. If Mellon does not identify itself identically to
|
|
what appears in the matching metadata, various SAML security checks
|
|
will fail as well as the ability to communicate on the defined
|
|
<<endpoints>>.
|
|
|
|
At run time Mellon asks Apache what scheme, host and port it's running
|
|
under. Mellon uses this information to build URLs. When Mellon is
|
|
running in a simple configuration directly connected to the internet,
|
|
Apache typically gets this information correctly from the
|
|
environment. However when Apache is behind some type of proxy such as
|
|
a load balancer, then there is a distinction between what clients see
|
|
as the front end and what Mellon sees when it's running as a backend
|
|
server. The trick is to make Mellon believe it's running as the front
|
|
end so that it matches the client's view. You may wish to refer to
|
|
<<load_balancer>> for more information.
|
|
|
|
Load balancers partition their view between front end and back end.
|
|
|
|
front end:: What the client connects to. It's the public scheme,
|
|
hostname, and port.
|
|
|
|
back end:: The back end server is where Mellon runs. It will
|
|
definitely have a different hostname than the front end and will
|
|
likely also have a different scheme and port as well.
|
|
|
|
When a HTTP request arrives at the front end most load balancers will
|
|
terminate the SSL connection. This changes the scheme from `https` to
|
|
`http`. The load balancer will select a backend server to forward the
|
|
request to. The backend server will have a different hostname and
|
|
possibly a different port. Mellon needs to see the HTTP request as it
|
|
appeared on the front end instead of how the request appears to the
|
|
backend server where Mellon is running.
|
|
|
|
The host and port appear in several contexts:
|
|
|
|
* The host and port in the URL the client used.
|
|
* The host HTTP header inserted into the HTTP request (derived from
|
|
the client URL host).
|
|
* The hostname of the front facing proxy the client connects to
|
|
(actually the FQDN of the IP address the proxy is listening on).
|
|
* The host and port of the backend server which actually handled the client
|
|
request.
|
|
* The **virtual** host and port of the server that actually handled the client
|
|
request.
|
|
|
|
It is vital to understand how each of these is utilized, otherwise
|
|
there is the opportunity for the wrong host and port to be used with
|
|
the consequence the authentication protocols may fail because they
|
|
cannot validate who the parties in the transaction are and whether the
|
|
data is carried in a secure transport.
|
|
|
|
Let's begin with the backend server handling the request, because this
|
|
is where the host and port are evaluated and most of the problems
|
|
occur. The backend server needs to know:
|
|
|
|
* The URL of the request (including host & port)
|
|
* Its own host & port
|
|
|
|
Apache supports virtual name hosting. This allows a single server to
|
|
host multiple domains. For example a server running on example.com
|
|
might service requests for both bigcorp.com and littleguy.com. The
|
|
latter 2 names are virtual host names. Virtual hosts in Apache
|
|
are configured inside a server configuration block, for example:
|
|
|
|
----
|
|
<VirtualHost>
|
|
ServerName bigcorp.com
|
|
</VirtualHost>
|
|
----
|
|
|
|
When Apache receives a request it deduces the host from the `HOST`
|
|
HTTP header. It then tries to match the host to the `ServerName` in
|
|
its collection of virtual hosts.
|
|
|
|
The Apache `ServerName` directive sets the request scheme, hostname
|
|
and port that the server uses to identify itself. The behavior of the
|
|
`ServerName` directive is modified by the Apache `UseCanonicalName`
|
|
directive. When `UseCanonicalName` is enabled Apache will use the
|
|
hostname and port specified in the `ServerName` directive to construct
|
|
the canonical name for the server. This name is used in all
|
|
self-referential URLs, and for the values of SERVER_NAME and
|
|
SERVER_PORT in CGIs. If `UseCanonicalName` is `Off`, Apache will form
|
|
self-referential URLs using the hostname and port supplied by the
|
|
client, if any are supplied.
|
|
|
|
If no port is specified in the `ServerName`, then the server will use
|
|
the port from the incoming request. For optimal reliability and
|
|
predictability, you should specify an explicit hostname and port using
|
|
the `ServerName` directive. If no `ServerName` is specified, the
|
|
server attempts to deduce the host by first asking the operating
|
|
system for the system hostname, and if that fails, performs a reverse
|
|
lookup on an IP address present on the system. Obviously this will
|
|
produce the wrong host information when the server is behind a proxy
|
|
because the backend server is not what is seen on the frontend
|
|
by clients; therefore use of the `ServerName` directive is essential.
|
|
|
|
NOTE: [[standard_port_issue]] Browsers will strip standard port 80 for
|
|
HTTP and port 443 for HTTPS from the network location in a URL. For
|
|
example if you specify a URL like this
|
|
`https://example.com:443/some/path` the URL which will placed on the
|
|
wire will be `https://example.com/some/path` without the standard
|
|
port. Since Mellon and most SAML providers validate URLs by simple
|
|
string comparison, including a standard port in a URL will cause URL
|
|
matching to fail because one URL will have the port in it and the
|
|
other URL won't.
|
|
|
|
The Apache
|
|
https://httpd.apache.org/docs/current/mod/core.html#servername>[ServerName]
|
|
doc is very clear concerning the need to fully specify the scheme,
|
|
host, and port in the `Server` name directive when the server is
|
|
behind a proxy. It states:
|
|
|
|
____
|
|
Sometimes, the server runs behind a device that processes SSL,
|
|
such as a reverse proxy, load balancer or SSL offload
|
|
appliance. When this is the case, specify the https:// scheme and
|
|
the port number to which the clients connect in the ServerName
|
|
directive to make sure that the server generates the correct
|
|
self-referential URLs.
|
|
____
|
|
|
|
=== Load Balancer Issues [[load_balancer]]
|
|
|
|
High Availability (HA) deployments often run their services behind a
|
|
load balancer. By far the most popular load balancer is
|
|
http://www.haproxy.com/[HAProxy]. As a consequence we will use HAProxy
|
|
examples in this document. Other load balancers behave in a similar
|
|
fashion to HAProxy and you can extrapolate the HAProxy information to
|
|
them.
|
|
|
|
==== Server Name
|
|
|
|
Because backend servers do not self-identify with the same front end
|
|
public address, it is vital you force those Apache servers to identify
|
|
with the public address. This issue is described in
|
|
<<apache_servername>>. The reason for this is because the SAML
|
|
protocols require URLs to match what is in a SAML provider's
|
|
metadata. If you allow a backend server to self-identify, the URLs
|
|
exchanged in the protocols will not match and you will encounter an
|
|
error; see <<invalid_destination>>.
|
|
|
|
==== Load balancer proxy persistence [[load_balancer_persistence]]
|
|
|
|
In an HA deployment, multiple backend servers run on distinct nodes and
|
|
cooperate to mitigate the load that might be placed on a single
|
|
(front end) server. Because the backend servers are independent, they
|
|
do not share state with any other backend server unless something has
|
|
explicitly been done to share state. HTTP is technically a stateless
|
|
protocol, which makes web traffic ideally suited for a HA deployment:
|
|
each backend server can be ignorant of any other HTTP request. However
|
|
in practice HTTP is stateful by virtue of cookies. Authentication
|
|
protocols are good examples of HTTP transactions that require saved
|
|
state, in particular <<mellon_session, Mellon sessions>>.
|
|
|
|
NOTE: At the time of this writing Mellon has no support for sharing session
|
|
data between independent Apache servers. The consequence of this is
|
|
Mellon will not work correctly unless the same Apache server
|
|
consistently handles a users HTTP traffic.
|
|
|
|
HAProxy has two different mechanisms to bind HTTP traffic to one
|
|
server, _affinity_ and _persistence_. This article provides an
|
|
excellent overview of the distinction between the two and how to
|
|
implement it: http://www.haproxy.com/blog/load-balancing-affinity-persistence-sticky-sessions-what-you-need-to-know/["load balancing, affinity, persistence, sticky sessions: what you need to know"].
|
|
|
|
What is the difference between Persistence and Affinity? Affinity is
|
|
when information from a layer below the application layer is used to
|
|
pin a client request to a single server. Persistence is when
|
|
application layer information binds a client to a single server sticky
|
|
session. The main advantage of persistence over affinity is
|
|
it is much more accurate.
|
|
|
|
Persistence is implemented though the use of cookies. The HAProxy
|
|
`cookie` directive names the cookie which will be used for
|
|
persistence, along with parameters controlling its use. The HAProxy
|
|
`server` directive has a `cookie` option that sets the value of
|
|
the cookie: it should be set to the name of the server. If an incoming
|
|
request does not have a cookie identifying the backend server, then
|
|
HAProxy selects a server based on its configured balancing
|
|
algorithm. HAProxy assures that the cookie is set to the name of the
|
|
selected server in the response. If the incoming request has a cookie
|
|
identifying a backend server, then HAProxy automatically selects that
|
|
server to handle the request.
|
|
|
|
To enable persistence in the backend server block of the
|
|
`/etc/haproxy/haproxy.cfg` configuration this line must be added:
|
|
|
|
----
|
|
cookie SERVERID insert indirect nocache
|
|
----
|
|
|
|
This says `SERVERID` will be the name of our HAProxy persistence
|
|
cookie. Then we must edit each `server` line and add `cookie
|
|
<server-name>` as an additional option. For example:
|
|
|
|
----
|
|
server server-0 cookie server-0
|
|
server server-1 cookie server-1
|
|
----
|
|
|
|
Note, the other parts of the server directive have been omitted for
|
|
clarity.
|
|
|
|
NOTE: The <<mellon_cookie,Mellon session cookie>> and the HAProxy
|
|
server persistence cookie are entirely separate. Do not confuse
|
|
them. The HAProxy server persistence cookie identifies the backend
|
|
server which issued the Mellon cookie.
|
|
|
|
For Mellon to work correctly, all user requests *must* be handled by
|
|
the same backend server that issued the Mellon cookie in the first place.
|
|
|
|
|
|
=== Forwarded HTTP Headers [[forwarded_http_headers]]
|
|
|
|
When proxies are in effect the `X-Forwarded-\*` HTTP headers come
|
|
into play. These are set by proxies and are meant to allow an entity
|
|
processing a request to recognize that the request was forwarded and
|
|
what the original values were _before_ being forwarded.
|
|
|
|
A common HAProxy configuration sets the `X-Forwarded-Proto` HTTP
|
|
header based on whether the front connection utilized SSL/TLS or not
|
|
via this configuration::
|
|
|
|
http-request set-header X-Forwarded-Proto https if { ssl_fc }
|
|
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
|
|
|
|
To make matters interesting, core Apache *does not* interpret this
|
|
header; thus responsibility falls to someone else to process it. In the
|
|
situation where HAProxy terminates SSL prior to the backend server
|
|
processing the request, the fact that the `X-Forwarded-Proto` HTTP header
|
|
is set to https is *irrelevant* because Apache does not utilize the
|
|
header when an extension module such as Mellon asks for the protocol
|
|
scheme of the request. This is why it is *essential* to have the
|
|
`ServerName` directive include the `scheme:://host:port` and to have
|
|
`UseCanonicalName` enabled: otherwise Apache extension modules such
|
|
as Mellon will not function properly behind a proxy.
|
|
|
|
But what about web apps hosted by Apache behind a proxy? It turns out
|
|
it's the web app's (or rather the web app framework's) responsibility to
|
|
process the forwarded header. Thus apps handle the protocol scheme of
|
|
a forwarded request differently than Apache extension modules do.
|
|
|
|
The critical thing to note is is that Apache extension modules and web
|
|
apps process the request scheme of a forwarded request differently,
|
|
demanding that *both* the `ServerName` and `X-Forwarded-Proto` HTTP
|
|
header techniques be utilized.
|
|
|
|
== When a SAML party responds with an error [[error_response]]
|
|
|
|
SAML is a request/response protocol much like HTTP. In fact the two
|
|
major SAML datatypes are `Request` and `Response`. A `Response`
|
|
contains a `Status` element which includes a `StatusCode` indicating
|
|
if the `Request` succeeded or failed, and if it failed, the reason
|
|
why. The `StatusCode` element may contain additional nested
|
|
`StatusCode` elements providing additional details, but typically
|
|
there is usually only one or two `StatusCode` elements. The outermost
|
|
`StatusCode` is called the top-level status code, the next nested
|
|
`StatusCode` is called the second-level status code. `StatusCode`
|
|
values *must* be a URI. The top-level status codes *must* be one of
|
|
one of the top-level status codes defined by the SAML specification. The
|
|
second-level status code must also be a URI and should be one of the
|
|
second-level status codes defined by SAML but a system entity may
|
|
define its own non-top-level status codes.
|
|
|
|
In addition to the `StatusCode` elements a `Status` element may also
|
|
contain an optional `StatusMessage` with greater detail and/or a
|
|
`StatusDetail` whose format is not defined by SAML.
|
|
|
|
In most scenarios Mellon, acting as a relying party, issues a
|
|
`Request` to an IdP acting as an asserting party, which then replies
|
|
with a `Response` containing a `Status`. Occasionally Mellon will
|
|
receive a `Request` from an IdP for which Mellon will respond with a
|
|
`Response` and `Status`; a good example of this is IdP-initiated
|
|
logout.
|
|
|
|
*When diagnosing problems you should examine the `StatusCode` values
|
|
and any additional information in the `Status` element.*
|
|
|
|
=== Top-level status codes
|
|
|
|
Below are top-level status codes as defined by SAML.
|
|
|
|
.Top-level status codes
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:Success::
|
|
|
|
The request succeeded. Additional information MAY be returned in the
|
|
<StatusMessage> and/or <StatusDetail> elements.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:Requester::
|
|
|
|
The request could not be performed due to an error on the part of the
|
|
requester.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:Responder::
|
|
|
|
The request could not be performed due to an error on the part of the
|
|
SAML responder or SAML authority.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:VersionMismatch::
|
|
|
|
The SAML responder could not process the request because the version
|
|
of the request message was incorrect.
|
|
|
|
=== Second-level status codes
|
|
|
|
Below are second-level status codes as defined by SAML.
|
|
|
|
.Second-level status codes
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:AuthnFailed::
|
|
|
|
The responding provider was unable to successfully authenticate the
|
|
principal.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:InvalidAttrNameOrValue::
|
|
|
|
Unexpected or invalid content was encountered within a
|
|
<saml:Attribute> or <saml:AttributeValue> element.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy::
|
|
|
|
The responding provider cannot or will not support the requested name
|
|
identifier policy.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:NoAuthnContext::
|
|
|
|
The specified authentication context requirements cannot be met by the
|
|
responder.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:NoAvailableIDP::
|
|
|
|
Used by an intermediary to indicate that none of the supported
|
|
identity provider <Loc> elements in an <IDPList> can be resolved or
|
|
that none of the supported identity providers are available.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:NoPassive::
|
|
|
|
Indicates the responding provider cannot authenticate the principal
|
|
passively, as has been requested.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:NoSupportedIDP::
|
|
|
|
Used by an intermediary to indicate that none of the identity
|
|
providers in an <IDPList> are supported by the intermediary.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:PartialLogout::
|
|
|
|
Used by a session authority to indicate to a session participant that
|
|
it was not able to propagate logout to all other session participants.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:ProxyCountExceeded::
|
|
|
|
Indicates that a responding provider cannot authenticate the principal
|
|
directly and is not permitted to proxy the request further.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:RequestDenied::
|
|
|
|
The SAML responder or SAML authority is able to process the request
|
|
but has chosen not to respond. This status code MAY be used when
|
|
there is concern about the security context of the request message or
|
|
the sequence of request messages received from a particular requester.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:RequestUnsupported::
|
|
|
|
The SAML responder or SAML authority does not support the request.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:RequestVersionDeprecated::
|
|
|
|
The SAML responder cannot process any requests with the protocol
|
|
version specified in the request.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooHigh::
|
|
|
|
The SAML responder cannot process the request because the protocol
|
|
version specified in the request message is a major upgrade from the
|
|
highest protocol version supported by the responder.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooLow::
|
|
|
|
The SAML responder cannot process the request because the protocol
|
|
version specified in the request message is too low.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:ResourceNotRecognized::
|
|
|
|
The resource value provided in the request message is invalid or
|
|
unrecognized.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:TooManyResponses::
|
|
|
|
The response message would contain more elements than the SAML
|
|
responder is able to return.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:UnknownAttrProfile::
|
|
|
|
An entity that has no knowledge of a particular attribute profile has
|
|
been presented with an attribute drawn from that profile.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal::
|
|
|
|
The responding provider does not recognize the principal specified or
|
|
implied by the request.
|
|
|
|
urn:oasis:names:tc:SAML:2.0:status:UnsupportedBinding::
|
|
|
|
The SAML responder cannot properly fulfill the request using the
|
|
protocol binding specified in the request.
|
|
|
|
=== Status code examples
|
|
|
|
.Example of a `Status` indicating success.
|
|
[source,xml]
|
|
----
|
|
<samlp:Status>
|
|
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> <!--1-->
|
|
</samlp:Status>
|
|
----
|
|
|
|
<1> _Top-level status code:_ Because the top-level status code is
|
|
`Success` no other status information is included.
|
|
|
|
[[invalid_nameid_example]]
|
|
.Example of a `Status` indicating failure due to invalid NameIDPolicy.
|
|
[source,xml]
|
|
----
|
|
<samlp:Status>
|
|
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Requester"> <!--1-->
|
|
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy"/> <!--2-->
|
|
</samlp:StatusCode>
|
|
</samlp:Status>
|
|
----
|
|
|
|
<1> _Top-level status code:_ Because the top-level status code is
|
|
*not* `Success` this top-level status code indicates a *failure* and
|
|
the _primary_ reason for the failure. In this instance, the requester
|
|
sent a value the receiver was unable to process.
|
|
|
|
<2> _Second-level status code:_ This second-level status code provides
|
|
the additional information describing what the requester sent that
|
|
could not be acted upon. In this case, the requester sent a
|
|
`NameIDPolicy` the IdP was unable to fulfill.
|
|
|
|
=== Finding the `StatusCode` [[find_status_code]]
|
|
|
|
Recent versions of Mellon (>= 0.13.1) will log any non-success status
|
|
in both the Apache error log and in the Mellon diagnostics log (if
|
|
enabled). The log message for the above `InvalidNameIDPolicy` error
|
|
will look like this:
|
|
|
|
----
|
|
"StatusCode1="urn:oasis:names:tc:SAML:2.0:status:Requester", StatusCode2="urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy", "StatusMessage="(null)"
|
|
----
|
|
|
|
Or you have the option to examine the SAML message as described in <<gather_runtime_info>>.
|
|
|
|
== Gathering run-time information [[gather_runtime_info]]
|
|
|
|
=== Apache log files
|
|
|
|
Mellon writes messages to the Apache server error log file. Depending
|
|
on your Apache configuration, those messages might appear in either
|
|
`/var/log/httpd/error_log` or `/var/log/httpd/ssl_error_log`. You can
|
|
turn up the verbosity of the messages by modifying the Apache
|
|
`LogLevel`, for example:
|
|
|
|
----
|
|
LogLevel debug
|
|
----
|
|
|
|
NOTE: Mellon's use of standard Apache logging is limited. See
|
|
<<mellon_diagnostics>> for a much better way to capture Mellon run
|
|
time information.
|
|
|
|
=== Trace SAML flow [[trace_saml_flow]]
|
|
|
|
Since you're most likely using the SAML Web-SSO profile, which is
|
|
entirely browser based, you can use any of the browser tools to watch
|
|
HTTP requests and responses. The Firefox web browser provides the
|
|
FireBug add-on and the Chrome browser offers Developer Tools. Each of
|
|
these browsers also has additional add-ons to display SAML messages;
|
|
see <<inspect_saml_messages>>.
|
|
|
|
NOTE: The easiest and most complete way to trace HTTP requests and
|
|
responses during SAML flow, capture SAML messages, and examine how
|
|
Mellon processes a SAML message is to use <<mellon_diagnostics>>.
|
|
|
|
=== Inspect SAML messages [[inspect_saml_messages]]
|
|
|
|
There are many times when you need to see the content of a SAML
|
|
message. Perhaps you don't know what attributes your IdP is returning
|
|
in an assertion. Or the SAML transaction is failing for some reason
|
|
and you need to diagnose why. In such cases being able to see the
|
|
contents of the SAML messages can be immensely helpful.
|
|
|
|
Examining the on-the-wire SAML data is seldom useful, even when it's
|
|
contained in otherwise visible HTTP data elements such as query
|
|
parameters, post data, etc. This is because the various SAML bindings
|
|
encode the message in different ways. It may break the message into
|
|
independent components which need to be reassembled at the receiving
|
|
end, or it may encode the data in a variety of formats which need to be
|
|
decoded to recover the original message content. It's best to use SAML-aware
|
|
tools to examine SAML messages, because they know how to decode
|
|
and reassemble the raw SAML data into the final SAML message the
|
|
receiver evaluates.
|
|
|
|
NOTE: The easiest and most complete way to capture SAML messages and
|
|
examine how Mellon processes a SAML message is to use
|
|
<<mellon_diagnostics>>. If your version of Mellon supports diagnostics
|
|
you may wish to skip to this section.
|
|
|
|
The Web-SSO SAML profile is by far the most commonly used. Because all
|
|
SAML messages transit though the browser in Web-SSO, it is possible to
|
|
write a browser extension to capture and decode the SAML messages
|
|
exchanged between the SP and IdP.
|
|
|
|
==== Firefox SAML Tracer [[saml_tracer]]
|
|
|
|
The Firefox
|
|
https://addons.mozilla.org/en-US/firefox/addon/saml-tracer/[SAML
|
|
Tracer] Add-On will display decoded SAML messages used during single
|
|
sign-on and single logout. SAML Tracer is not capable of decrypting
|
|
an encrypted IdP response, because it does not have access to the IdP's
|
|
public encryption key contained in the IdP's metadata. See
|
|
<<encrypted_response>> for how to deal with this issue.
|
|
|
|
To use SAML Tracer you must first install the add-on. Then each time
|
|
you want to use SAML Tracer you will need to go to the Firefox menu
|
|
and select the SAML Tracer option. This will bring up a separate
|
|
Firefox window which looks like this:
|
|
|
|
image::saml-tracer.svg[]
|
|
|
|
The SAML Tracer window is divided into two panes: a list of
|
|
HTTP requests in the top pane, and detailed information on the selected
|
|
request in the bottom window.
|
|
|
|
SAML Tracer examines each HTTP request and response, and if it detects
|
|
it is a SAML message, it flags the request in the request list window
|
|
at the top with a "SAML" icon.
|
|
|
|
In the detail pane are different tabs which show you the
|
|
request/response information in different views. In order to view the
|
|
decoded SAML message you need to make the `SAML` tab active. The
|
|
`Parameters` tab shows you the query parameters (either URL or POST).
|
|
SAML messages are usually transported in HTTP parameters, so this is
|
|
where you can see the raw SAML data before being decoded into a
|
|
complete SAML message. The `http` tab shows you the HTTP headers
|
|
associated with the HTTP request/response.
|
|
|
|
==== Chrome, SAML Chrome Panel
|
|
|
|
The Chrome Web browser offers several add-ons to display SAML
|
|
messages. The most commonly used is
|
|
https://chrome.google.com/webstore/detail/saml-chrome-panel/paijfdbeoenhembfhkhllainmocckace[SAML
|
|
Chrome Panel]. SAML Chrome Panel integrates with the Chrome developer
|
|
tools.
|
|
|
|
Here is an example of the SAML Chrome Panel in the developer tools
|
|
panel:
|
|
|
|
image::chrome_SAML_Chrome_Panel.svg[]
|
|
|
|
==== If the IdP response is encrypted [[encrypted_response]]
|
|
|
|
Data in a SAML response may be encrypted for confidentiality (usually
|
|
encryption is not needed because SAML transactions should be occurring
|
|
over a secure TLS channel). Decrypting the data requires access to the
|
|
IdP's public encryption key contained in its metadata. Most SAML
|
|
browser tools do not support decryption. If you discover your tool is
|
|
showing you encrypted data you have a few options:
|
|
|
|
* Disable encryption at the IdP. See your IdP's documentation on how
|
|
to enable/disable encryption.
|
|
|
|
* Use <<mellon_diagnostics>>. The diagnostics support in Mellon
|
|
operates after the SAML message is decoded from its SAML binding
|
|
transport and after it's been decrypted into a final plaintext SAML
|
|
XML document. Most people will find Mellon diagnostics to be the
|
|
easiest and most complete capture of SAML data and Mellon's processing
|
|
of it.
|
|
|
|
=== Inspecting Mellon environment variables [[inspect_mellon_env]]
|
|
|
|
Recall that Mellon communicates with web apps by inserting Apache
|
|
environment variables into the Apache environment. While diagnosing
|
|
problems or when initially setting up your Mellon deployment it can be
|
|
very useful to see the contents of the Apache environment. The typical
|
|
way this is done is to substitute the resource Mellon is protecting
|
|
with a script that dumps the environment it received. So instead of
|
|
getting back the resource, after Mellon successfully authenticates the
|
|
script runs and returns a page listing the environment variables. Once
|
|
you've collected this information you need to remove the script from
|
|
the protected URL so the protected resource will be returned
|
|
instead of a data dump.
|
|
|
|
If your installed version of Mellon includes support for
|
|
<<mellon_diagnostics>>, there is no need to alter your protected
|
|
resource in order to get an environment variable dump. The diagnostics
|
|
log includes a dump of the complete Apache environment at the end of
|
|
each response. This is a much easier and more complete solution than
|
|
substituting a script for your protected resource.
|
|
|
|
==== Python WSGI Environment Dump
|
|
|
|
Create a script with the following content:
|
|
|
|
[source,python]
|
|
----
|
|
import pprint
|
|
import webob
|
|
import webob.dec
|
|
|
|
|
|
@webob.dec.wsgify
|
|
def application(req):
|
|
return webob.Response(pprint.pformat(req.environ),
|
|
content_type='application/json')
|
|
|
|
----
|
|
|
|
Placing the above script in the Apache `cgi-bin` directory is a good
|
|
idea. We'll name this script 'dump-env'.
|
|
|
|
Add a `WSGIScriptAlias` directive to your Apache configuration so that
|
|
it runs the above script when the protected resource URL is
|
|
requested. For example:
|
|
|
|
----
|
|
WSGIScriptAlias "/private/info.html" "/var/www/cgi-bin/dump-env"
|
|
----
|
|
|
|
|
|
==== PHP Environment Dump
|
|
|
|
[source,php]
|
|
----
|
|
<?php
|
|
header('Content-Type: text/plain');
|
|
|
|
foreach($_SERVER as $key=>$value) {
|
|
if(substr($key, 0, 7) == 'MELLON_') {
|
|
echo($key . '=' . $value . "\r\n");
|
|
}
|
|
}
|
|
?>
|
|
|
|
----
|
|
|
|
|
|
=== Mellon Diagnostics [[mellon_diagnostics]]
|
|
|
|
When something goes wrong with your Mellon deployment, experience has
|
|
shown that it can be frustratingly difficult to gather sufficient
|
|
information to diagnose the problem. Often you will need access to the
|
|
following pieces of information:
|
|
|
|
* Mellon configuration
|
|
* Mellon metadata
|
|
* IdP metadata
|
|
* HTTP requests and responses
|
|
* HTTP headers
|
|
* SAML message content as decoded pretty XML
|
|
* Apache environment variables
|
|
* Session infomation
|
|
|
|
Although Mellon does log some `DEBUG` messages to the Apache error log,
|
|
that information is often incomplete and mixed in with other
|
|
irrelevant messages. The SAML message content has to be gathered
|
|
independently via other tools (<<inspect_saml_messages>>), configuring
|
|
Apache to log all HTTP headers is obscure and verbose, there is no
|
|
easy way to log all Apache environment variables associated with a
|
|
request, and the SAML metadata and Mellon configuration is independent of
|
|
the log data. Finally all these indpendent pieces of data gathered from
|
|
multiple sources need to be correlated to produce a coherent
|
|
sequence while at the same time removing a lot of extraneous irrelevant
|
|
non-SAML data.
|
|
|
|
Apache logging also suffers from some serious limitations when trying
|
|
to record SAML data. Apache enforces a hard limit on the length of a
|
|
log message, which often results in truncating SAML messages. Apache
|
|
log messages are reformatted, newlines are removed, and other characters
|
|
are escaped. This makes trying to read XML documents extremely
|
|
difficult unless you post-process the log.
|
|
|
|
If you are a support person trying to help an administrator with their
|
|
Mellon deployment, it is very difficult to get a 3rd party who is not
|
|
familiar with the various operations to gather the necessary
|
|
information in a cohesive form amenable for remote diagnostic review.
|
|
|
|
It would be really nice if Mellon could gather all this information in
|
|
protocol sequence in a single file without other irrelevant Apache
|
|
messages, and without the need for any post-processing of the log data.
|
|
|
|
Mellon has been extended to gather all the above relevant information
|
|
in a human readable format. The feature is called _Mellon
|
|
Diagnostics_. The diagnostics feature is new as of July 2017, and it
|
|
must be enabled at compile time; thus your version of Mellon may not
|
|
have it. Because the feature is new the format and content of the
|
|
diagnostic data is expected to evolve.
|
|
|
|
==== Using Mellon Diagnostics [[using_mellon_diagnostics]]
|
|
|
|
Currently Mellon diagnostics supports these new Mellon
|
|
directives. These directives are module level and as such should be
|
|
declared outside of any location blocks in your Apache configuration.
|
|
|
|
MellonDiagnosticFile::
|
|
If Mellon was built with diagnostic capability then diagnostic is
|
|
written here, it may be either a filename or a pipe. If it's a
|
|
filename then the resulting path is relative to the ServerRoot. If
|
|
the value is preceeded by the pipe character "|" it should be followed
|
|
by a path to a program to receive the log information on its standard
|
|
input. Default: `logs/mellon_diagnostics`
|
|
|
|
MellonDiagnosticEnable::
|
|
If Mellon was built with diagnostic capability then this is a list of
|
|
words controlling diagnostic output. Currently only `On` and `Off` are
|
|
supported. Default: `Off`
|
|
|
|
To enable diagnostic logging add this line to your Apache
|
|
configuration file where you keep your Mellon configuration.
|
|
|
|
----
|
|
MellonDiagnosticEnable On
|
|
----
|
|
|
|
Restart Apache and perform some operation that involves Mellon. In
|
|
your Apache log directory will be a file called `mellon_diagnostics`
|
|
(or whatever `MellonDiagnosticFile` was set to).
|
|
|
|
IMPORTANT: Diagnostic logging may potentially contain security
|
|
sensitive information. Diagnostic logging is verbose and will generate
|
|
large files. Therefore _you should enable diagnostic logging only for
|
|
the minimum duration necessary_.
|
|
|
|
You may wish to review diagnostic output in
|
|
<<mellon_diagnostics_example>> captured when the demo authentication
|
|
was executed.
|
|
|
|
== Potential Problems
|
|
|
|
=== It's the metadata
|
|
|
|
*The vast majority of SAML deployment problems can be traced
|
|
back to metadata.*
|
|
|
|
* Is your metadata current?
|
|
* Have you loaded your most recent SP metadata? Did you restart Apache
|
|
after modifying the SP metadata?
|
|
* Has your IdP loaded the exactly the same metadata Mellon is reading
|
|
at Apache start-up?
|
|
* Have you loaded your most recent IdP metadata? Did you restart Apache
|
|
after modifying the SP metadata?
|
|
* Did you make a change to your entityID?
|
|
* Did you make a change to the `MellonEndpointPath` without
|
|
regenerating your SP metadata and loading the new metadata into both
|
|
Mellon and your IdP? Remember the `MellonEndpointPath` establishes
|
|
all the SAML endpoint URLs that appear in your metadata.
|
|
See <<incorrect_mellon_endpoint_path>> and <<mellon_endpoint_path>>.
|
|
* Did you modify any of the keys or certs without both updating the
|
|
mellon config _and_ your SP metadata?
|
|
|
|
=== Behavior does not change after modifying any SAML file
|
|
|
|
Mellon reads its configuration at Apache start-up. If you make any
|
|
change to any file Mellon reads, you will not see those changes
|
|
reflected until after you restart Apache.
|
|
|
|
=== Are the Mellon configuration directives syntactically correct?
|
|
|
|
Apache will not start if there is any error in any of the
|
|
configuration files it reads. An easy way to test the correctness of
|
|
your Apache configuration directives _without starting the server and
|
|
examining the error logs_ is to use the the `apachectl`
|
|
command line tool with the `configtest` option:
|
|
|
|
----
|
|
apachectl configtest
|
|
----
|
|
|
|
=== No AuthnRequest sent to IdP
|
|
|
|
During debugging you may discover the entire <<web_sso_flow, Web-SSO
|
|
flow>> is not executed, so the IdP is never contacted. This is because
|
|
Mellon implements sessions. The session identifier is communicated in
|
|
the cookie `mellon-cookie` (or whatever is the current value of the
|
|
Mellon directive `MellonVariable`). If you had previously
|
|
successfully authenticated against the IdP, the browser will have been
|
|
sent the Mellon session ID in its cookie. When Mellon gets a request
|
|
to authenticate a resource, it first checks to see if it has a valid
|
|
session based on the identifier passed as the Mellon cookie. If there
|
|
is a valid session, Mellon will use that cached session information
|
|
instead of contacting the IdP. Deleting the `mellon-cookie` from the
|
|
browser will cause Mellon to believe there is no pre-existing
|
|
session.
|
|
|
|
=== Incorrect MellonEndpointPath [[incorrect_mellon_endpoint_path]]
|
|
|
|
. <<mellon_endpoint_path,`MellonEndpointPath`>>
|
|
|
|
[listing,subs="verbatim,quotes"]
|
|
------------------------------------------
|
|
<Location />
|
|
MellonEndpointPath ##/mellon/## <!--1-->
|
|
</Location>
|
|
------------------------------------------
|
|
|
|
<1> The definition of `MellonEndpointPath` in your Apache Mellon
|
|
configuration *must* match the path component in each of your
|
|
Service `Location` declarations in your SP metadata. See
|
|
<<mellon_endpoint_path,MellonEndpointPath>> for more detail.
|
|
|
|
[listing,subs="verbatim,quotes"]
|
|
------------------------------------------
|
|
<SPSSODescriptor>
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://mellon.example.com##/mellon/##logout" /> <!--1-->
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://mellon.example.com##/mellon/##logout" /> <!--1-->
|
|
<AssertionConsumerService
|
|
index="0"
|
|
isDefault="true"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://mellon.example.com##/mellon/##postResponse" /> <!--1-->
|
|
<AssertionConsumerService
|
|
index="1"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
|
|
Location="https://mellon.example.com##/mellon/##artifactResponse" /> <!--1-->
|
|
<AssertionConsumerService
|
|
index="2"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS"
|
|
Location="https://mellon.example.com##/mellon/##paosResponse" /> <!--1-->
|
|
</SPSSODescriptor>
|
|
------------------------------------------
|
|
|
|
<1> Each Service `Location` URL in your SP metadata *must* have a path
|
|
component that starts with your `MellonEndpointPath` and appends
|
|
exactly one directory component to it. That final directory component
|
|
is one of the Mellon endpoints as described in
|
|
<<mellon_endpoints>>. Here the `MellonEndpointPath` is highlighted in
|
|
the `Location` attributes of the metadata.
|
|
|
|
=== HTTP_BAD_REQUEST - Invalid Destination on Response [[invalid_destination]]
|
|
|
|
If after posting the Assertion to your `postResponse` endpoint you get
|
|
a HTTP_BAD_REQUEST error with status code 400 and a page that says:
|
|
|
|
----
|
|
Your browser sent a request that this server could not understand.
|
|
----
|
|
|
|
and in the Apache log file there is a Mellon message like this:
|
|
|
|
----
|
|
Invalid Destination on Response. Should be: https://xxx/mellon/postResponse
|
|
----
|
|
|
|
Then you have failed one of the SAML security checks. There is a SAML
|
|
requirement that the recipient of a message verifies that the intended
|
|
destination of the message is the actual SAML endpoint it was received
|
|
on. This is to prevent malicious forwarding of messages to unintended
|
|
recipients.
|
|
|
|
To perform this check, what Mellon does is build a URL by asking Apache
|
|
what scheme, hostname, and port it is running under, and then appends
|
|
the <<mellon_endpoint_path,MellonEndpointPath>> and the Mellon
|
|
endpoint to it. This becomes the URL the message was received
|
|
on. Mellon then does a string comparison to see if this manufactured
|
|
URL is identical to the `Destination` attribute in the SAML
|
|
message. If they are not the same string, the test fails and a
|
|
HTTP_BAD_REQUEST is returned.
|
|
|
|
There are two potential causes for this failure:
|
|
|
|
. Incorrect Apache `ServerName`. See the <<apache_servername, Apache
|
|
ServerName>> discussion for more details. This problem usually occurs
|
|
when Mellon is running behind a load balancer or SSL terminator.
|
|
|
|
. Mismatch between the Mellon metadata and the `MellonEndpointPath` in
|
|
your Mellon configuration. If the scheme, hostname, and port are
|
|
correct then the problem must be in path component of the URL. The
|
|
SAML `Destination` attribute is read from the provider's metadata. The
|
|
`MellonEndpointPath` is read from Mellon's configuration. The two must
|
|
be in sync. Verify that the location endpoints in Mellon's metadata match
|
|
the value of `MellonEndpointPath`. See the discussion of
|
|
<<mellon_endpoint_path, MellonEndpointPath>> for more details.
|
|
The `Destination` check may also fail because one URL has an explicit
|
|
port but the other does not. This can occur with the standard HTTP port
|
|
80 and HTTPS port 443: see <<standard_port_issue, Standard Ports>> for
|
|
more detail.
|
|
|
|
=== Mellon metadata out of sync with Mellon configuration
|
|
|
|
Mellon's metadata and its Apache configuration directives
|
|
have data elements in common but are maintained independently. The
|
|
Apache configuration directives in common with the metadata are:
|
|
|
|
* `MellonSPentityId`
|
|
* `MellonSPPrivateKeyFile`
|
|
* `MellonSPCertFile`
|
|
* `MellonEndpointPath`
|
|
|
|
This can lead to problems if you:
|
|
|
|
* Generate metadata not consistent with these values in your Apache
|
|
configuration directives.
|
|
|
|
* Edit the above Apache configuration directives without regenerating
|
|
and reloading your metadata.
|
|
|
|
* Fail to load the current SP metadata by restarting Apache.
|
|
|
|
* Fail to load the current SP metadata into the IdP.
|
|
|
|
You may wish to review <<metadata_creation>> and <<mellon_endpoint_path>>.
|
|
|
|
=== Microsoft ADFS issues
|
|
|
|
It is common to have problems when using Microsoft ADFS as a SAML IdP.
|
|
|
|
This blog post from Microsoft contains many of the ADFS configuration
|
|
issues encountered when adding an SP to ADFS:
|
|
[[adfs_blog,ADFS Deep Dive Blog]]https://blogs.technet.microsoft.com/askpfeplat/2015/03/01/adfs-deep-dive-onboarding-applications/[ADFS Deep Dive Onboarding Applications]
|
|
|
|
NOTE: ADFS calls SPs a "Relying Party" and the SP configuration a
|
|
"Relying Party Trust".
|
|
|
|
==== ADFS Signature Algorithm [[adfs_sig_alg]]
|
|
|
|
One of the `Relying Party Trust` options is the "Secure Hash
|
|
Algorithm" which controls the signature algorithm used to produce an
|
|
XML signature on the SAML message. This is the signature algorithm
|
|
ADFS will use to sign the SAML messages it emits. SAML does not require
|
|
both parties to use the same signature algorithm; in theory, it's fine
|
|
if Mellon as the SP signs with one algorithm and ADFS as the IdP signs
|
|
with a different algorithm. But ADFS enforces the requirement that the
|
|
SP signs with same algorithm as set in the `Relying Party Trust`. If
|
|
ADFS receives a SAML message signed with a different algorithm than
|
|
what is specified in the `Relying Party Trust` configuration, you will
|
|
get a message in the ADFS log like this:
|
|
|
|
----
|
|
SAML request is not signed with expected signature algorithm. SAML
|
|
request is signed with signature algorithm
|
|
http://www.w3.org/2001/04/xmldsig-more#rsa-sha1 . Expected signature
|
|
algorithm is http://www.w3.org/2000/09/xmldsig#rsa-sha256
|
|
----
|
|
|
|
Since SHA-1 is no longer considered secure, many ADFS administrators set
|
|
their `Relying Party Trust` secure hash algorithm to SHA-256. This
|
|
causes problems for Mellon versions earlier than 0.13.1, which
|
|
always signed its messages with the SHA-1 hash (specifically the
|
|
RSA-SHA1 algorithm) and there was no mechanism to specify a
|
|
different signing algorithm. See <<adfs_blog>> for how to modify the
|
|
`Relying Party Trust` Secure Hash Algorithm.
|
|
|
|
Mellon versions greater than 0.13.1 added a new configuration option
|
|
called `MellonSignatureMethod` which allows you to match the signature
|
|
algorithm emitted by Mellon to the one specified in the ADFS `Relying
|
|
Party Trust` for the Mellon SP. For example:
|
|
|
|
----
|
|
MellonSignatureMethod rsa-sha256
|
|
----
|
|
|
|
|
|
==== ADFS NameIDPolicy [[adfs_nameid_policy]]
|
|
|
|
By default ADFS cannot handle many of the SAML NameID formats without
|
|
additional configuration in the `Relying Party Trust`. Please make
|
|
sure you are familiar with the material in the section <<name_id>>. By
|
|
default, Mellon will generate SP metadata with a
|
|
<<nameid_policy,NameIDPolicy>> of `transient`, see
|
|
<<specify_mellon_nameid>> for how to modify this in Mellon.
|
|
|
|
When ADFS receives a SAML message with a `NameIDPolicy` set to a
|
|
specific format, it is supposed to respond with a `NameID` matching that
|
|
format. Because of the architecture of ADFS, it may not have access to
|
|
the data needed to generate that `NameID`. The necessary data is
|
|
contained in a _Claim_ controlled by a _Claim Rule_. To get the
|
|
contents of the _Claim_ being used to populate the SAML `NameID`, you
|
|
must also add a `Claim Rule Transform` that maps the desired _Claim_
|
|
data into a SAML data element, which in this case is the `NameID`.
|
|
|
|
Examples of the `NameID` formats which require this additional
|
|
configuration in ADFS are `transient`, `persistent`, `email` and
|
|
possibly others. If the _Claim Rule_ and _Claim Rule Transform_ are
|
|
not configured for the `NameIDPolicy` in the request, ADFS will respond
|
|
with a `InvalidNameIDPolicy` error status because it cannot provide
|
|
the requested `NameID` format. See <<invalid_nameid_example, NameID
|
|
error example>> in the <<error_response, error response section>> for
|
|
an example of this error and how to identify it.
|
|
|
|
This Microsoft blog discusses `NameID` configuration in ADFS:
|
|
[[adfs_nameid,ADFS NameID Configuration]]https://blogs.msdn.microsoft.com/card/2010/02/17/name-identifiers-in-saml-assertions/[ADFS
|
|
- Name Identifiers in SAML assertions]
|
|
|
|
=== Time Sync
|
|
|
|
SAML, like many authentication protocols (e.g. Kerberos), relies on
|
|
timestamps to validate messages. If you see one of these errors in the
|
|
httpd logs:
|
|
|
|
----
|
|
[auth_mellon:error] [pid xxx] [client xxx] NotBefore in Condition was in the future.
|
|
[auth_mellon:error] [pid xxx] [client xxx] NotOnOrAfter in Condition was in the past.
|
|
----
|
|
|
|
Then it's likely that either the Mellon node or the IdP node are not time
|
|
synchronized. You can check the status of your time sync with the
|
|
`chronyc` command line tool, for example:
|
|
|
|
----
|
|
$ chronyc sources
|
|
210 Number of sources = 4
|
|
MS Name/IP address Stratum Poll Reach LastRx Last sample
|
|
===============================================================================
|
|
^? tock.no-such-agency.net 0 10 0 10y +0ns[ +0ns] +/- 0ns
|
|
^? static-74-104-167-114.bst 0 10 0 10y +0ns[ +0ns] +/- 0ns
|
|
^? 69.195.159.158 0 10 0 10y +0ns[ +0ns] +/- 0ns
|
|
^? freemont.nerdboy.net.au 0 10 0 10y +0ns[ +0ns] +/- 0ns
|
|
----
|
|
|
|
If the `Reach` column has zeros in it you are not synchronizing your
|
|
clock. This may be due to a firewall blocking the NTP port. Trying
|
|
opening your NTP port or using a different server in `/etc/chrony.conf`.
|
|
|
|
|
|
== Glossary
|
|
|
|
entityID:: The unique name of a SAML provider. The entityID *must* be
|
|
a URI. Often entityID's are URLs, however the choice of using a
|
|
URL as an entityID does not have any meaning in SAML other than it is
|
|
a convenient way to to have a unique URI. It is best to choose an
|
|
entityID that will not change over time as SAML services inevitably
|
|
migrate between hosts in a deployment. Once again, an entityID is *_a
|
|
unique name for a SAML service_*, it is nothing more than that.
|
|
|
|
Assertion:: Data produced by a SAML authority (e.g. IdP) with respect
|
|
to a specific subject. The assertion may convey authentication of the
|
|
subject, attributes associated with the subject, or authorization
|
|
information for the subject in regards to a specific resource.
|
|
|
|
Identity Provider:: An identity provider is a SAML authority which
|
|
_provides_ authentication services proving the identity of a
|
|
principal. The proof of identity is conveyed in a SAML assertion along
|
|
with additional information about the subject (attributes) which the
|
|
service provider may choose to utilize when making authorization
|
|
decisions.
|
|
|
|
IdP:: Acronym for Identity Provider
|
|
|
|
Profile::
|
|
A profile is a set of rules for one of several purposes; each set is given a
|
|
name in the pattern “xxx profile of SAML” or “xxx SAML profile”.
|
|
|
|
* Rules for how to embed assertions into and extract them
|
|
from a protocol or other context of use.
|
|
* Rules for using SAML protocol messages in a particular
|
|
context of use.
|
|
* Rules for mapping attributes expressed in SAML to
|
|
another attribute representation system. Such a set of
|
|
rules is known as an “attribute profile”.
|
|
|
|
SAML:: Security Assertion Markup Language.
|
|
|
|
Service Provider:: A service provider is a SAML _relying party_ which
|
|
_provides_ a _service_ to a user who must be authenticated and
|
|
authorized by the service in order to use the service. A web
|
|
application is a common example.
|
|
|
|
SP:: Acronym for Service Provider.
|
|
|
|
[appendix]
|
|
== Appendix
|
|
|
|
=== Example On-The-Wire AuthnRequest [[authentication_request_wire]]
|
|
|
|
This is is the "on the wire" HTTP data for the
|
|
<<authentication_request>> using the _HTTP Redirect Binding_.
|
|
|
|
----
|
|
GET https://rhsso.example.com:8443/auth/realms/test/protocol/saml?SAMLRequest=hZJBT8JAEIX%2FSrN32NKWAptCQkASEjQE1IMXs6lj2KS7W3emiv%2FeaRHFi5w2eTsvb76XKVDbqlbzhg5uB28NIEVHWzlU3cdUNMEpr9GgctoCKirVfn67UUk%2FVnXw5EtfiQvL%2Fw6NCIGMdyJaL6fieTgZJPkiTeP8JstHk1U%2BTOMkWcWLbDkfreJMRI8QkOengu1sQmxg7ZC0I5biwagX571kfD9IVTpRg%2BxJREtmME5T5zoQ1aikDAdE34ejtnUF%2FdJbNc6yVGrmlgF0ZVES%2B%2BQZSbYsIlp4h9BG%2FQdVnoZU2YTAb89whikNiWjlQwldt1PxqiuElmDLJZh3%2BFHm507asMZC2EN4NyU87Da%2F%2B1uoKu8uAb4lWXukHWDdLiFmRbu36moKs%2BtmC6RfNOlCXvqK01HcMel6ufUM89miWH2liFYxL73XblRR0A4NF8KIHPax4J6JsSk0IOTsFPn39GZf&RelayState=https%3A%2F%2Fmellon.example.com%2Fprivate%2Finfo.html&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=GJ%2BC%2BEwcPpOmAfYwMdMcAPSkX2y1Da634jrm1oWWs8Ozyb7P%2FumIk9HaNbfJZvaHc6HyOxYXhCpqb6NJrRm%2BrY1NSOJqjtt3kXldNLKecFfhKamzfOfAufKTPGGSZNAuwRTiQCkrLuFt8A%2BezEuCswNDADSRJGLL9aYX8A8G23IcLeVuqobtrCH9bSr2wgO0uy61o1s5bDlA6ceKwrjle%2F6TofFUWBYOB6pzRL40AzmNsvKieHqSOCxo6uNKQdEZQYomF9fi%2FuCPovIn5AdRFC1wcx%2BeGYi%2BDS6R4lbEnrhu8RfEmxhA8PJHDoTMH2fcfD0jyUh%2BejtLdqCUFJ9ppQ%3D%3D HTTP/1.1
|
|
----
|
|
|
|
=== Example On-the-Wire <Assertion> response [[assertion_response_wire]]
|
|
|
|
This is is the "on the wire" HTTP data for the <<assertion_response>>
|
|
using the _HTTP Post Binding_.
|
|
|
|
----
|
|
<HTML><HEAD><TITLE>SAML HTTP Post Binding</TITLE></HEAD><BODY Onload=\"document.forms[0].submit()\"><FORM METHOD=\"POST\" ACTION=\"https://mellon.example.com/mellon/postResponse\"><INPUT TYPE=\"HIDDEN\" NAME=\"SAMLResponse\" VALUE=\"PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIERlc3RpbmF0aW9uPSJodHRwczovL21lbGxvbi5leGFtcGxlLmNvbS9tZWxsb24vcG9zdFJlc3BvbnNlIiBJRD0iSURfZDA2ZGFhYWYtNjRlYy00NGQzLTk1YTctMDhkYTg5M2FhOWQ1IiBJblJlc3BvbnNlVG89Il81OTEyNkMzMzA2RTQ2NzlGNjUzMDIyRjBDNERBN0YwNCIgSXNzdWVJbnN0YW50PSIyMDE3LTA2LTI4VDEzOjM5OjI3LjMzMVoiIFZlcnNpb249IjIuMCI+PHNhbWw6SXNzdWVyIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iPmh0dHBzOi8vcmhzc28uZXhhbXBsZS5jb206ODQ0My9hdXRoL3JlYWxtcy90ZXN0PC9zYW1sOklzc3Vlcj48ZHNpZzpTaWduYXR1cmUgeG1sbnM6ZHNpZz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+PGRzaWc6U2lnbmVkSW5mbz48ZHNpZzpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PGRzaWc6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxkc2lnLW1vcmUjcnNhLXNoYTI1NiIvPjxkc2lnOlJlZmVyZW5jZSBVUkk9IiNJRF9kMDZkYWFhZi02NGVjLTQ0ZDMtOTVhNy0wOGRhODkzYWE5ZDUiPjxkc2lnOlRyYW5zZm9ybXM+PGRzaWc6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHNpZzpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L2RzaWc6VHJhbnNmb3Jtcz48ZHNpZzpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGVuYyNzaGEyNTYiLz48ZHNpZzpEaWdlc3RWYWx1ZT5WLzNpWW9oR3YyT3Q3cHp5NnEvQmZBZFhnU3htZENEN0srWEVtRklabFVzPTwvZHNpZzpEaWdlc3RWYWx1ZT48L2RzaWc6UmVmZXJlbmNlPjwvZHNpZzpTaWduZWRJbmZvPjxkc2lnOlNpZ25hdHVyZVZhbHVlPk1peDZHL2IrL09TWG1SdWp1MzNzN3IyNWNiV0F5dVNIU3RCOE55UGJ6NGJVK0VGZ09qWGg2SmIyK1NrMXFaeXNwYmxXTWpMMS96WDhCU3NwZTNiT0FOSTErNDZqQ1lwOE1pNUFlM0VhMzZkeGlDMG1wM0dwYUdRUXkzanMzY2tFdUVsY1cvTU10RjlmQ003YkV1M09CdjRCZVNZSVRkMW9sNEV5WndxTllScmQ2ck1wbk1CQUVvSlZ1d09mLzhYVWdoQVc3Mk9kdnNNN2VQd00zeWd3K0dMOXM5T3VVSGU3MFVhUTlyTVpVMWZpVXozQldLMTNXR3Qzc09nbjdsK0c4REcxOEE2K2RVVXJxbzFvQkl4bEh3Q01RazRaVHhZVU9HSlJmbmFVNHVBeWtKbDRqT2FwUWVSZ2JnNWR5NGpla3c3Wlk1QXFUbUdEd0V3b0xwWmtvQT09PC9kc2lnOlNpZ25hdHVyZVZhbHVlPjxkc2lnOktleUluZm8+PGRzaWc6S2V5TmFtZT4xVlBuZGpmQUJCNlM0bGI0endNTGpCVWh4ZnpQRm5mcnZOWXZSZ2N4aVVNPC9kc2lnOktleU5hbWU+PGRzaWc6WDUwOURhdGE+PGRzaWc6WDUwOUNlcnRpZmljYXRlPk1JSUNsekNDQVg4Q0JnRmNZTWMzNERBTkJna3Foa2lHOXcwQkFRc0ZBREFQTVEwd0N3WURWUVFEREFSMFpYTjBNQjRYRFRFM01EVXpNVEl6TURrME4xb1hEVEkzTURVek1USXpNVEV5TjFvd0R6RU5NQXNHQTFVRUF3d0VkR1Z6ZERDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSXg3QmhaV1lZR2NKVVh1YjZhR3VLV0wxZnY3TjQwSE04bTc0ZFVRcWZzR1R4U2VlWS91eUNLKzBYU0crU1E3K2ptTFA3Rjk1bmhTQXp4R1FhaHByemdIOUlTQTBXT2tkSVk1ZTFwY1Z0SERaUTM2dzZMMUxhdHlaWitPNHA5V1JvOStMZ0NPNWc4eFZwSE84ZWxkU3hycjBQRDJMWTBWUy91d0RCdmMxUWpPS0tYR0dhQ3RZQXRDa3NnUlV3b3hvR0VhOWh3MHN2SWhZZVBlSjh4dlIrRWRKT3RrTHJjdE12Tk9PWUd2TDZ5U0FYK2NRRUVRM1R3RFZJRlR6cFFpRGpZYjhIblVoMExEOVg4M3gvbjdhdGV1YlFmRGNMUkE5clZWM2lXT3Q1SmR6SVNiSVR0UDNnSU1oUlpoK0dRSmxCZkxrWThnRHFlRDdWSG5aR09QM244Q0F3RUFBVEFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBSkE5cUt6TnhPU0FmRmdLejlMZlkzbHFMQ3c0RXM1VTI1QW9ZY3MxRENRbWljclpuUVNRdUxWQXJoSEJBelRsbmFsWHo2aE1FZjh5YXIzd242a3ZKMXdUaDJJK3dDb2w4aVROckV0K3lpaUdzYXgrVG1ZMkxFWCtpdG9zMkFUeEFNL3dJY0xaaTJSamRva2xqakQ3cVpyVVBiVEVTQnczTnFOOERJN0gwcEVPYWNDTVR2bUFhNVRmeXpkTGxKbzYyUWFraWpZelZsTi9kSVQ2UlkxdytwV0o3TzRSL0Fyci9XMlI4aHl4SEF3QVIxOGRBa1pWWkUyRjZ0TUFqWkx5WnZiaEZnTjBWMHdhdWpBbGw0K1RnNHhsWWdMMGI5M3dEZzJiWmJURmh5NjdyVUJqbHFLMWRxb2ZXVzdiMUgwRG54eElYeVE3aENCRzVxUnd3eXQ3Z1JBPT08L2RzaWc6WDUwOUNlcnRpZmljYXRlPjwvZHNpZzpYNTA5RGF0YT48ZHNpZzpLZXlWYWx1ZT48ZHNpZzpSU0FLZXlWYWx1ZT48ZHNpZzpNb2R1bHVzPmpIc0dGbFpoZ1p3bFJlNXZwb2E0cFl2VisvczNqUWN6eWJ2aDFSQ3Ard1pQRko1NWorN0lJcjdSZEliNUpEdjZPWXMvc1gzbWVGSURQRVpCcUdtdk9BZjBoSURSWTZSMGhqbDdXbHhXMGNObERmckRvdlV0cTNKbG40N2luMVpHajM0dUFJN21EekZXa2M3eDZWMUxHdXZROFBZdGpSVkwrN0FNRzl6VkNNNG9wY1lab0sxZ0MwS1N5QkZUQ2pHZ1lScjJIRFN5OGlGaDQ5NG56RzlINFIwazYyUXV0eTB5ODA0NWdhOHZySklCZjV4QVFSRGRQQU5VZ1ZQT2xDSU9OaHZ3ZWRTSFFzUDFmemZIK2Z0cTE2NXRCOE53dEVEMnRWWGVKWTYza2wzTWhKc2hPMC9lQWd5RkZtSDRaQW1VRjh1Ump5QU9wNFB0VWVka1k0L2Vmdz09PC9kc2lnOk1vZHVsdXM+PGRzaWc6RXhwb25lbnQ+QVFBQjwvZHNpZzpFeHBvbmVudD48L2RzaWc6UlNBS2V5VmFsdWU+PC9kc2lnOktleVZhbHVlPjwvZHNpZzpLZXlJbmZvPjwvZHNpZzpTaWduYXR1cmU+PHNhbWxwOlN0YXR1cz48c2FtbHA6U3RhdHVzQ29kZSBWYWx1ZT0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnN0YXR1czpTdWNjZXNzIi8+PC9zYW1scDpTdGF0dXM+PHNhbWw6QXNzZXJ0aW9uIHhtbG5zPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiBJRD0iSURfYzQ2M2ExNDEtZDQ3MS00MGMzLTg2MGEtNjU1OWNlMGEzNTU2IiBJc3N1ZUluc3RhbnQ9IjIwMTctMDYtMjhUMTM6Mzk6MjcuMzMxWiIgVmVyc2lvbj0iMi4wIiB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIj48c2FtbDpJc3N1ZXIgeG1sbnM6c2FtbD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+aHR0cHM6Ly9yaHNzby5leGFtcGxlLmNvbTo4NDQzL2F1dGgvcmVhbG1zL3Rlc3Q8L3NhbWw6SXNzdWVyPjxkc2lnOlNpZ25hdHVyZSB4bWxuczpkc2lnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj48ZHNpZzpTaWduZWRJbmZvPjxkc2lnOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48ZHNpZzpTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNyc2Etc2hhMjU2Ii8+PGRzaWc6UmVmZXJlbmNlIFVSST0iI0lEX2M0NjNhMTQxLWQ0NzEtNDBjMy04NjBhLTY1NTljZTBhMzU1NiI+PGRzaWc6VHJhbnNmb3Jtcz48ZHNpZzpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxkc2lnOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPjwvZHNpZzpUcmFuc2Zvcm1zPjxkc2lnOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI3NoYTI1NiIvPjxkc2lnOkRpZ2VzdFZhbHVlPnc4YkVMUnNodFg3eEhjd1pDZGdsZ2ZweVlCTUptVlFKQUxQQWNsSEhiTEE9PC9kc2lnOkRpZ2VzdFZhbHVlPjwvZHNpZzpSZWZlcmVuY2U+PC9kc2lnOlNpZ25lZEluZm8+PGRzaWc6U2lnbmF0dXJlVmFsdWU+QlVhbHc4cDcvRWIrcHNIOHZRd08zbWZSc2l2bmlQZkZJRmtaSWtMNlBYbXNQRmczejgvcVFjUkNXSThOQ1NMcENzUGU1VG9YSnBvQyt5NkVUU2tCUG55WGw3MXhqMkxQdTFOanl3TkVFTGk5NFc1bFlvek1PUzh2akd0OUpLcFFhdVp0SEs2Q2xsclJLZE02N1ArWlBSb21PS0wyRnoxQVBaeGFWNW9ueEt0U0lXVFBoRHE1anF4bzE4a3RxMHZXcUg1VUJCTG92S1kydlNodDFJcWVLdzczZ2ROTXpEUTVyd1d3NXFIMjlUcTZzeHllYjJPR3JGS2VySkRuZ1F4aHRCK0R6K1cyUEZuMG9IdEVERXByWkxaRXdxVm5EcTIvTVlvcHdCV3VSM2YzL3BPeTRZOTJvS21XUm01TWVURlo1T1Y0YlZZRS9PRzZPdnUrc2xBdEdRPT08L2RzaWc6U2lnbmF0dXJlVmFsdWU+PGRzaWc6S2V5SW5mbz48ZHNpZzpLZXlOYW1lPjFWUG5kamZBQkI2UzRsYjR6d01MakJVaHhmelBGbmZydk5ZdlJnY3hpVU08L2RzaWc6S2V5TmFtZT48ZHNpZzpYNTA5RGF0YT48ZHNpZzpYNTA5Q2VydGlmaWNhdGU+TUlJQ2x6Q0NBWDhDQmdGY1lNYzM0REFOQmdrcWhraUc5dzBCQVFzRkFEQVBNUTB3Q3dZRFZRUUREQVIwWlhOME1CNFhEVEUzTURVek1USXpNRGswTjFvWERUSTNNRFV6TVRJek1URXlOMW93RHpFTk1Bc0dBMVVFQXd3RWRHVnpkRENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFJeDdCaFpXWVlHY0pVWHViNmFHdUtXTDFmdjdONDBITThtNzRkVVFxZnNHVHhTZWVZL3V5Q0srMFhTRytTUTcram1MUDdGOTVuaFNBenhHUWFocHJ6Z0g5SVNBMFdPa2RJWTVlMXBjVnRIRFpRMzZ3NkwxTGF0eVpaK080cDlXUm85K0xnQ081Zzh4VnBITzhlbGRTeHJyMFBEMkxZMFZTL3V3REJ2YzFRak9LS1hHR2FDdFlBdENrc2dSVXdveG9HRWE5aHcwc3ZJaFllUGVKOHh2UitFZEpPdGtMcmN0TXZOT09ZR3ZMNnlTQVgrY1FFRVEzVHdEVklGVHpwUWlEalliOEhuVWgwTEQ5WDgzeC9uN2F0ZXViUWZEY0xSQTlyVlYzaVdPdDVKZHpJU2JJVHRQM2dJTWhSWmgrR1FKbEJmTGtZOGdEcWVEN1ZIblpHT1AzbjhDQXdFQUFUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFKQTlxS3pOeE9TQWZGZ0t6OUxmWTNscUxDdzRFczVVMjVBb1ljczFEQ1FtaWNyWm5RU1F1TFZBcmhIQkF6VGxuYWxYejZoTUVmOHlhcjN3bjZrdkoxd1RoMkkrd0NvbDhpVE5yRXQreWlpR3NheCtUbVkyTEVYK2l0b3MyQVR4QU0vd0ljTFppMlJqZG9rbGpqRDdxWnJVUGJURVNCdzNOcU44REk3SDBwRU9hY0NNVHZtQWE1VGZ5emRMbEpvNjJRYWtpall6VmxOL2RJVDZSWTF3K3BXSjdPNFIvQXJyL1cyUjhoeXhIQXdBUjE4ZEFrWlZaRTJGNnRNQWpaTHladmJoRmdOMFYwd2F1akFsbDQrVGc0eGxZZ0wwYjkzd0RnMmJaYlRGaHk2N3JVQmpscUsxZHFvZldXN2IxSDBEbnh4SVh5UTdoQ0JHNXFSd3d5dDdnUkE9PTwvZHNpZzpYNTA5Q2VydGlmaWNhdGU+PC9kc2lnOlg1MDlEYXRhPjxkc2lnOktleVZhbHVlPjxkc2lnOlJTQUtleVZhbHVlPjxkc2lnOk1vZHVsdXM+akhzR0ZsWmhnWndsUmU1dnBvYTRwWXZWKy9zM2pRY3p5YnZoMVJDcCt3WlBGSjU1ais3SUlyN1JkSWI1SkR2Nk9Zcy9zWDNtZUZJRFBFWkJxR212T0FmMGhJRFJZNlIwaGpsN1dseFcwY05sRGZyRG92VXRxM0psbjQ3aW4xWkdqMzR1QUk3bUR6RldrYzd4NlYxTEd1dlE4UFl0alJWTCs3QU1HOXpWQ000b3BjWVpvSzFnQzBLU3lCRlRDakdnWVJyMkhEU3k4aUZoNDk0bnpHOUg0UjBrNjJRdXR5MHk4MDQ1Z2E4dnJKSUJmNXhBUVJEZFBBTlVnVlBPbENJT05odndlZFNIUXNQMWZ6ZkgrZnRxMTY1dEI4Tnd0RUQydFZYZUpZNjNrbDNNaEpzaE8wL2VBZ3lGRm1INFpBbVVGOHVSanlBT3A0UHRVZWRrWTQvZWZ3PT08L2RzaWc6TW9kdWx1cz48ZHNpZzpFeHBvbmVudD5BUUFCPC9kc2lnOkV4cG9uZW50PjwvZHNpZzpSU0FLZXlWYWx1ZT48L2RzaWc6S2V5VmFsdWU+PC9kc2lnOktleUluZm8+PC9kc2lnOlNpZ25hdHVyZT48c2FtbDpTdWJqZWN0PjxzYW1sOk5hbWVJRCBGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpuYW1laWQtZm9ybWF0OnRyYW5zaWVudCIgeG1sbnM6c2FtbD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+Ry04MDM1MjhhYS0yZjllLTQ1NGItYTg5Yy01NWVlNzRlNzVkMWU8L3NhbWw6TmFtZUlEPjxzYW1sOlN1YmplY3RDb25maXJtYXRpb24gTWV0aG9kPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6Y206YmVhcmVyIj48c2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uRGF0YSBJblJlc3BvbnNlVG89Il81OTEyNkMzMzA2RTQ2NzlGNjUzMDIyRjBDNERBN0YwNCIgTm90T25PckFmdGVyPSIyMDE3LTA2LTI4VDEzOjQ0OjI1LjMzMVoiIFJlY2lwaWVudD0iaHR0cHM6Ly9tZWxsb24uZXhhbXBsZS5jb20vbWVsbG9uL3Bvc3RSZXNwb25zZSIvPjwvc2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uPjwvc2FtbDpTdWJqZWN0PjxzYW1sOkNvbmRpdGlvbnMgTm90QmVmb3JlPSIyMDE3LTA2LTI4VDEzOjM5OjI1LjMzMVoiIE5vdE9uT3JBZnRlcj0iMjAxNy0wNi0yOFQxMzo0MDoyNS4zMzFaIj48c2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPjxzYW1sOkF1ZGllbmNlPmh0dHBzOi8vbWVsbG9uLmV4YW1wbGUuY29tL21lbGxvbi9tZXRhZGF0YTwvc2FtbDpBdWRpZW5jZT48L3NhbWw6QXVkaWVuY2VSZXN0cmljdGlvbj48L3NhbWw6Q29uZGl0aW9ucz48c2FtbDpBdXRoblN0YXRlbWVudCBBdXRobkluc3RhbnQ9IjIwMTctMDYtMjhUMTM6Mzk6MjcuMzMyWiIgU2Vzc2lvbkluZGV4PSI5YjZhNDZiOS0yOGYyLTRjZTEtYjE1MS03MTMyNDA1MjBlNWQiPjxzYW1sOkF1dGhuQ29udGV4dD48c2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6Y2xhc3Nlczp1bnNwZWNpZmllZDwvc2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj48L3NhbWw6QXV0aG5Db250ZXh0Pjwvc2FtbDpBdXRoblN0YXRlbWVudD48c2FtbDpBdHRyaWJ1dGVTdGF0ZW1lbnQ+PHNhbWw6QXR0cmlidXRlIEZyaWVuZGx5TmFtZT0iTGlzdCBvZiBncm91cHMiIE5hbWU9Imdyb3VwcyIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDpiYXNpYyI+PHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5pcGF1c2Vyczwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT48c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPm9wZW5zdGFjay11c2Vyczwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT48L3NhbWw6QXR0cmlidXRlPjxzYW1sOkF0dHJpYnV0ZSBGcmllbmRseU5hbWU9ImVtYWlsIiBOYW1lPSJlbWFpbCIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDpiYXNpYyI+PHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5qZG9lQG11c2ljLmNvbTwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT48L3NhbWw6QXR0cmlidXRlPjxzYW1sOkF0dHJpYnV0ZSBGcmllbmRseU5hbWU9IkRpc3BsYXkgTmFtZSIgTmFtZT0iZGlzcGxheV9uYW1lIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj48c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPkpvaG4gRG9lPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPjwvc2FtbDpBdHRyaWJ1dGU+PHNhbWw6QXR0cmlidXRlIEZyaWVuZGx5TmFtZT0iaW5pdGlhbHMiIE5hbWU9ImluaXRpYWxzIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj48c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPkpEPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPjwvc2FtbDpBdHRyaWJ1dGU+PHNhbWw6QXR0cmlidXRlIEZyaWVuZGx5TmFtZT0iTGFzdCBOYW1lIiBOYW1lPSJsYXN0X25hbWUiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6YmFzaWMiPjxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI+RG9lPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPjwvc2FtbDpBdHRyaWJ1dGU+PHNhbWw6QXR0cmlidXRlIEZyaWVuZGx5TmFtZT0iRmlyc3QgTmFtZSIgTmFtZT0iZmlyc3RfbmFtZSIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDpiYXNpYyI+PHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5Kb2huPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPjwvc2FtbDpBdHRyaWJ1dGU+PHNhbWw6QXR0cmlidXRlIE5hbWU9IlJvbGUiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6YmFzaWMiPjxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI+dW1hX2F1dGhvcml6YXRpb248L3NhbWw6QXR0cmlidXRlVmFsdWU+PC9zYW1sOkF0dHJpYnV0ZT48c2FtbDpBdHRyaWJ1dGUgTmFtZT0iUm9sZSIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDpiYXNpYyI+PHNhbWw6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHM6c3RyaW5nIj5tYW5hZ2UtYWNjb3VudDwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT48L3NhbWw6QXR0cmlidXRlPjxzYW1sOkF0dHJpYnV0ZSBOYW1lPSJSb2xlIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj48c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPnZpZXctcHJvZmlsZTwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT48L3NhbWw6QXR0cmlidXRlPjwvc2FtbDpBdHRyaWJ1dGVTdGF0ZW1lbnQ+PC9zYW1sOkFzc2VydGlvbj48L3NhbWxwOlJlc3BvbnNlPg==\"/><INPUT TYPE=\"HIDDEN\" NAME=\"RelayState\" VALUE=\"https://mellon.example.com/private/info.html\"/><NOSCRIPT><P>JavaScript is disabled. We strongly recommend to enable it. Click the button below to continue.</P><INPUT TYPE=\"SUBMIT\" VALUE=\"CONTINUE\" /></NOSCRIPT></FORM></BODY></HTML>
|
|
----
|
|
|
|
=== Example Mellon Diagnostics [[mellon_diagnostics_example]]
|
|
|
|
Here is the diagnostics output as described in <<mellon_diagnostics>>
|
|
for our authentication example.
|
|
|
|
----
|
|
---------------------------------- New Request ---------------------------------
|
|
GET - /saml-test/protected.html
|
|
log_id: (null)
|
|
server: name=/etc/httpd/conf.d/ssl.conf, scheme=https hostname=mellon.example.com port=443
|
|
pid: 21576, tid: 140251630954624
|
|
unparsed_uri: /saml-test/protected.html
|
|
uri: /saml-test/protected.html
|
|
path_info:
|
|
filename: /var/www/html/saml-test/protected.html
|
|
query args: (null)
|
|
Request Headers:
|
|
Host: mellon.example.com
|
|
Connection: keep-alive
|
|
Cache-Control: max-age=0
|
|
Upgrade-Insecure-Requests: 1
|
|
User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36
|
|
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
|
|
DNT: 1
|
|
Accept-Encoding: gzip, deflate, br
|
|
Accept-Language: en-US,en;q=0.8
|
|
Cookie: mellon-cookie=aa8aefac8bc813f194b1a8d97e3a4058
|
|
Mellon Directory Configuration for URL: /saml-test/protected.html
|
|
MellonEnable (enable): auth
|
|
MellonVariable (varname): cookie
|
|
MellonSecureCookie (secure): Off
|
|
MellonMergeEnvVars (merge_env_vars): (null)
|
|
MellonEnvVarsIndexStart (env_vars_index_start): -1
|
|
MellonEnvVarsSetCount (env_vars_count_in_n): On
|
|
MellonCookieDomain (cookie_domain): (null)
|
|
MellonCookiePath (cookie_path): (null)
|
|
MellonCond (cond): 0 items
|
|
MellonSetEnv (envattr): 0 items
|
|
MellonUser (userattr): NAME_ID
|
|
MellonIdP (idpattr): IDP
|
|
MellonSessionDump (dump_session): Off
|
|
MellonSamlResponseDump (dump_saml_response): Off
|
|
MellonEndpointPath (endpoint_path): /mellon/
|
|
MellonSPMetadataFile (sp_metadata_file):
|
|
pathname: "/etc/httpd/saml2/demo_sp_metadata.xml"
|
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
|
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
|
|
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
|
|
entityID="https://mellon.example.com/mellon/metadata">
|
|
<SPSSODescriptor
|
|
AuthnRequestsSigned="true"
|
|
WantAssertionsSigned="true"
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing">
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<KeyDescriptor use="encryption">
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
|
<AssertionConsumerService
|
|
index="0"
|
|
isDefault="true"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://mellon.example.com/mellon/postResponse" />
|
|
<AssertionConsumerService
|
|
index="1"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
|
|
Location="https://mellon.example.com/mellon/artifactResponse" />
|
|
<AssertionConsumerService
|
|
index="2"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS"
|
|
Location="https://mellon.example.com/mellon/paosResponse" />
|
|
</SPSSODescriptor>
|
|
</EntityDescriptor>
|
|
MellonSPPrivateKeyFile (sp_private_key_file):
|
|
pathname: "/etc/httpd/saml2/demo.key"
|
|
-----BEGIN PRIVATE KEY-----
|
|
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHUXILDtuMxyFP
|
|
6OW81hqfj9z+gC7sxR6U8bRPI4gFiNjkNF+4HMyrKtVtfwA5WJ1tJ4IaZbg4fGap
|
|
iCcWQ5tjjuZ7CpZ6XLekq63OGrkgZxNm8L+AjvREv78iR4Myc4x6ybN1LwQnV+oD
|
|
F0i9SAEPnfJCaCA+1+DC3RKy7+xtK3SVimUWwAHmkNU6N0wCVSNYn1KgnxBSCPTx
|
|
2DifbyRl21SiokCfLSnktE++WBzRzldSxzMrkSfFoS7/uT232tbdw2NsJmHGLRGk
|
|
myBrEC6BVhQ746NM1cLDtrOots7bNfZ3yfb3W1tpoKVOhM2se3OTKdidAQsaGlVu
|
|
7QIhBqinAgMBAAECggEBAJtU662WfJ9vqJRgCnpp2QG02iM0vl0jGbw1ybFLHXxC
|
|
s9TUxCv1tcNHdGEK8p++YaFpgskTsMfEmzVPuDZvpa+m9BO7op3ll/CrIp5W0SNh
|
|
cQtuX6/OuKrDTC9oz+QHjNk8S7DtXS1UJDkYckWg0cLb8qqx/z86eh0isKnmtLg2
|
|
H1+6L6mB9fcZldkcrU+kXT+dcDX85skMZAeBsrG4yaoX26AzVl8lEl2rJAQvpxj8
|
|
5wGBC4riWY6TzMYiCjcS5JfZIlbhcZe61ej3A48NVBSKCP1XKo0xbKuOHIQuMeeW
|
|
wSaboBwRzJ9JdTXlq5UWfLvmjXDc/HCwk/N7cj021uECgYEA5KkQr3cSKrMIkYoO
|
|
H0Vnkw1kYYGUjtTL00Nfdkv7uGMF122nyt1ND0gpdS0jgNx3LSEam/gY35UWEjGH
|
|
i8DGD04k8pvKDUsl8cuYPcC3oce1lLCGAnw+aHPC5wtA829CLOLtBfxXIhVAI0tp
|
|
ECosD/A63/m1LC19XolOd10/PC8CgYEA3yZChEYZupDGJFZltiy0ZgUarvD2Ss4N
|
|
QiRVR+CmpBrOKZdD8q6uUuqWQN9Rw7kXm8LxAPYwiIDVjxjYALF+j7/9Q1oZyKuv
|
|
eHJdMe4eRUeqeaIKbxnFfKwGZ5rj97jwPrkUCxio75KZhpOcDHMSgBCBtzW0XIZl
|
|
gTeQYOshZQkCgYB5TK6LRnEesabj/gaL1DejrMEJcMIsGvqdceocSSaZo/4fUA5o
|
|
8YjFiJRlkrJ403ttN1h0UOJxCReSQzASlQr8Z4n2IWrILotMf6Kdb7R6YAUVgac1
|
|
fk9k/bPw+OlVujmyshbmy/w1GmzRzFlJt/Vz5w50bnULoH4XPmOfspmvBQKBgBcJ
|
|
rihVzGY0eCBcQxfxuZYmxMB25BaI+1luwtcu3EVo9wvYMA2n9xtcWLLN23UncMaF
|
|
87ezswMEugeR+wrnSDezDISdkrfi8bSvqetzt/BTG8h+8DDUKk1avTaJCSwUDcmL
|
|
9gPHQfmp2uvH5X5riudpzNqLUtmSjnwurlszKzlxAoGAR8STlDJhNph+p3cF8k25
|
|
ydT1kypxnjzVG8CAV5/h3dUmc7j7gyV8NlWZfWacxMZWOBsrdVh0zhMNUPiLJaGd
|
|
I1isOkmiN9JFYMMhHSnhPnTCIjmu6uBLxf8wotHAvzWOJPV7lUZbw21KIN3DS79F
|
|
sGZ2QzGYn4inHG4UHClhZxU=
|
|
-----END PRIVATE KEY-----
|
|
MellonSPCertFile (sp_cert_file):
|
|
pathname: "/etc/httpd/saml2/demo.cert"
|
|
-----BEGIN CERTIFICATE-----
|
|
MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=
|
|
-----END CERTIFICATE-----
|
|
MellonIdPPublicKeyFile (idp_public_key_file):
|
|
file_data: NULL
|
|
MellonIdPCAFile (idp_ca_file):
|
|
file_data: NULL
|
|
MellonIdPMetadataFile (idp_metadata): 1 items
|
|
[ 0] Metadata
|
|
pathname: "/etc/httpd/saml2/demo_keycloak_ipa_idp_metadata.xml"
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!--
|
|
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
~ and other contributors as indicated by the @author tags.
|
|
~
|
|
~ 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.
|
|
-->
|
|
|
|
<EntitiesDescriptor Name="urn:keycloak" xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
|
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
|
|
<EntityDescriptor entityID="https://rhsso.example.com:8443/auth/realms/ipa">
|
|
<IDPSSODescriptor WantAuthnRequestsSigned="true"
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing">
|
|
<dsig:KeyInfo>
|
|
<dsig:KeyName>R2OGk9W0luNm_NtZbURWOrPlvFzSTDMimCVK5N1Mj5U</dsig:KeyName>
|
|
<dsig:X509Data>
|
|
<dsig:X509Certificate>MIIClTCCAX0CBgFeFdE9pDANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDDANpcGEwHhcNMTcwODI0MTk1NDQ3WhcNMjcwODI0MTk1NjI3WjAOMQwwCgYDVQQDDANpcGEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgIPeag+JJmhtAkIGBwUT/req+jKC6c0Vl1Ngtzbcd07CP9mq1DomBkjuWl59J2urlEfrV4yT8avia0eYE6Dm/TqC74SHt3TVtiUliynAh/z2JvFlLb/EbGePSKrMnuNV8rV75YGcyE12vBRooUPx3hGaygsfaSOg+BijDuCSpbVdWSdVx9VecsWJfxSochOZUj6yvm/qTb8Ptl0x/o7/b/16GgjFRIKSFrdk8pVtMn1wCzpQQoGVHZmp1jrppGcp8KXIK54q7b4pPiTzlW6xhBgrmW2RtWQesCmN8ga1CVeBZKLsaH7argwGH5Ttz31iensqUO0degFu6nwCltgTVAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFx8dl6RDle65q3IHIiGaL5fbJK5HxQiMXpk4N5riWQTP4g6xoTNAG4OFFUd4uRxt2ovdEdkbzhEy2lV4x626QdEfK5V9QKppupsTxTGA/4NMW9QCocAvFSpmYErmJIhfy6zzELoBK4Dpfcc3u1peHx2686msx6ExARF116d+5Xaps1dmPPy3yb2cCKzKbLhieqv+aLLrwz657ERUc4OnqEMEmmHFhHvPI7LRlS4AQ1/s1QlKcM9yqcu8WN3yKM/kuvZtZ0YTCSIl9W1b+I5v8wNoVFB22s7rfxs3DfJFaIImaTmRzaDX0MXgibEckrkigpO+anKe9B9z8CJdtlUHco=</dsig:X509Certificate>
|
|
</dsig:X509Data>
|
|
</dsig:KeyInfo>
|
|
</KeyDescriptor>
|
|
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
|
|
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleSignOnService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleSignOnService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
</IDPSSODescriptor>
|
|
</EntityDescriptor>
|
|
</EntitiesDescriptor>
|
|
[ 0] Chain File
|
|
file_data: NULL
|
|
MellonIdPIgnore (idp_ignore):
|
|
MellonSPentityId (sp_entity_id): (null)
|
|
MellonOrganizationName (sp_org_name): 0 items
|
|
MellonOrganizationDisplayName (sp_org_display_name): 0 items
|
|
MellonOrganizationURL (sp_org_url): 0 items
|
|
MellonSessionLength (session_length): -1
|
|
MellonNoCookieErrorPage (no_cookie_error_page): (null)
|
|
MellonNoSuccessErrorPage (no_success_error_page): (null)
|
|
MellonDefaultLoginPath (login_path): /
|
|
MellonDiscoveryURL (discovery_url): (null)
|
|
MellonProbeDiscoveryTimeout (probe_discovery_timeout): -1
|
|
MellonProbeDiscoveryIdP (probe_discovery_idp): 0 items
|
|
MellonAuthnContextClassRef (authn_context_class_ref): 0 items
|
|
MellonAuthnContextComparisonType (authn_context_comparison_type): (null)
|
|
MellonSubjectConfirmationDataAddressCheck (subject_confirmation_data_address_check): On
|
|
MellonDoNotVerifyLogoutSignature (do_not_verify_logout_signature): 0 items
|
|
MellonPostReplay (post_replay): On
|
|
MellonECPSendIDPList (ecp_send_idplist): On
|
|
enter function am_auth_mellon_user
|
|
searching for session with key aa8aefac8bc813f194b1a8d97e3a4058 (session) ... not found
|
|
am_auth_mellon_user am_enable_auth, no valid session
|
|
[APLOG_DEBUG auth_mellon_util.c:2055] have_paos_media_type=False valid_paos_header=False is_paos=Falseenter function am_start_auth
|
|
Loading SP Metadata
|
|
pathname: "/etc/httpd/saml2/demo_sp_metadata.xml"
|
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
|
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
|
|
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
|
|
entityID="https://mellon.example.com/mellon/metadata">
|
|
<SPSSODescriptor
|
|
AuthnRequestsSigned="true"
|
|
WantAssertionsSigned="true"
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing">
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<KeyDescriptor use="encryption">
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
|
<AssertionConsumerService
|
|
index="0"
|
|
isDefault="true"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://mellon.example.com/mellon/postResponse" />
|
|
<AssertionConsumerService
|
|
index="1"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
|
|
Location="https://mellon.example.com/mellon/artifactResponse" />
|
|
<AssertionConsumerService
|
|
index="2"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS"
|
|
Location="https://mellon.example.com/mellon/paosResponse" />
|
|
</SPSSODescriptor>
|
|
</EntityDescriptor>
|
|
Loading IdP Metadata
|
|
pathname: "/etc/httpd/saml2/demo_keycloak_ipa_idp_metadata.xml"
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!--
|
|
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
~ and other contributors as indicated by the @author tags.
|
|
~
|
|
~ 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.
|
|
-->
|
|
|
|
<EntitiesDescriptor Name="urn:keycloak" xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
|
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
|
|
<EntityDescriptor entityID="https://rhsso.example.com:8443/auth/realms/ipa">
|
|
<IDPSSODescriptor WantAuthnRequestsSigned="true"
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing">
|
|
<dsig:KeyInfo>
|
|
<dsig:KeyName>R2OGk9W0luNm_NtZbURWOrPlvFzSTDMimCVK5N1Mj5U</dsig:KeyName>
|
|
<dsig:X509Data>
|
|
<dsig:X509Certificate>MIIClTCCAX0CBgFeFdE9pDANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDDANpcGEwHhcNMTcwODI0MTk1NDQ3WhcNMjcwODI0MTk1NjI3WjAOMQwwCgYDVQQDDANpcGEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgIPeag+JJmhtAkIGBwUT/req+jKC6c0Vl1Ngtzbcd07CP9mq1DomBkjuWl59J2urlEfrV4yT8avia0eYE6Dm/TqC74SHt3TVtiUliynAh/z2JvFlLb/EbGePSKrMnuNV8rV75YGcyE12vBRooUPx3hGaygsfaSOg+BijDuCSpbVdWSdVx9VecsWJfxSochOZUj6yvm/qTb8Ptl0x/o7/b/16GgjFRIKSFrdk8pVtMn1wCzpQQoGVHZmp1jrppGcp8KXIK54q7b4pPiTzlW6xhBgrmW2RtWQesCmN8ga1CVeBZKLsaH7argwGH5Ttz31iensqUO0degFu6nwCltgTVAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFx8dl6RDle65q3IHIiGaL5fbJK5HxQiMXpk4N5riWQTP4g6xoTNAG4OFFUd4uRxt2ovdEdkbzhEy2lV4x626QdEfK5V9QKppupsTxTGA/4NMW9QCocAvFSpmYErmJIhfy6zzELoBK4Dpfcc3u1peHx2686msx6ExARF116d+5Xaps1dmPPy3yb2cCKzKbLhieqv+aLLrwz657ERUc4OnqEMEmmHFhHvPI7LRlS4AQ1/s1QlKcM9yqcu8WN3yKM/kuvZtZ0YTCSIl9W1b+I5v8wNoVFB22s7rfxs3DfJFaIImaTmRzaDX0MXgibEckrkigpO+anKe9B9z8CJdtlUHco=</dsig:X509Certificate>
|
|
</dsig:X509Data>
|
|
</dsig:KeyInfo>
|
|
</KeyDescriptor>
|
|
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
|
|
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleSignOnService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleSignOnService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
</IDPSSODescriptor>
|
|
</EntityDescriptor>
|
|
</EntitiesDescriptor>
|
|
[APLOG_DEBUG auth_mellon_handler.c:3498] Redirecting to login URL: https://mellon.example.com/mellon/login?ReturnTo=https%3A%2F%2Fmellon.example.com%2Fsaml%2Dtest%2Fprotected.html&IdP=https%3A%2F%2Frhsso.example.com%3A8443%2Fauth%2Frealms%2Fipa
|
|
=== Response ===
|
|
Status: 303 See Other(303)
|
|
user: (null) auth_type=(null)
|
|
Response Headers:
|
|
Cache-Control: private, max-age=0, must-revalidate
|
|
Location: https://mellon.example.com/mellon/login?ReturnTo=https%3A%2F%2Fmellon.example.com%2Fsaml%2Dtest%2Fprotected.html&IdP=https%3A%2F%2Frhsso.example.com%3A8443%2Fauth%2Frealms%2Fipa
|
|
Content-Length: 388
|
|
Keep-Alive: timeout=5, max=100
|
|
Connection: Keep-Alive
|
|
Content-Type: text/html; charset=iso-8859-1
|
|
Response Error Headers:
|
|
Environment:
|
|
UNIQUE_ID: WabkjcTYa6iga7y800KGZQAAAAA
|
|
---------------------------------- New Request ---------------------------------
|
|
GET - /mellon/login
|
|
log_id: (null)
|
|
server: name=/etc/httpd/conf.d/ssl.conf, scheme=https hostname=mellon.example.com port=443
|
|
pid: 21576, tid: 140251630954624
|
|
unparsed_uri: /mellon/login?ReturnTo=https%3A%2F%2Fmellon.example.com%2Fsaml%2Dtest%2Fprotected.html&IdP=https%3A%2F%2Frhsso.example.com%3A8443%2Fauth%2Frealms%2Fipa
|
|
uri: /mellon/login
|
|
path_info: /login
|
|
filename: /var/www/html/mellon
|
|
query args: ReturnTo=https%3A%2F%2Fmellon.example.com%2Fsaml%2Dtest%2Fprotected.html&IdP=https%3A%2F%2Frhsso.example.com%3A8443%2Fauth%2Frealms%2Fipa
|
|
Request Headers:
|
|
Host: mellon.example.com
|
|
Connection: keep-alive
|
|
Cache-Control: max-age=0
|
|
Upgrade-Insecure-Requests: 1
|
|
User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36
|
|
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
|
|
DNT: 1
|
|
Accept-Encoding: gzip, deflate, br
|
|
Accept-Language: en-US,en;q=0.8
|
|
Cookie: mellon-cookie=aa8aefac8bc813f194b1a8d97e3a4058
|
|
Mellon Directory Configuration for URL: /mellon/login
|
|
MellonEnable (enable): info
|
|
MellonVariable (varname): cookie
|
|
MellonSecureCookie (secure): Off
|
|
MellonMergeEnvVars (merge_env_vars): (null)
|
|
MellonEnvVarsIndexStart (env_vars_index_start): -1
|
|
MellonEnvVarsSetCount (env_vars_count_in_n): On
|
|
MellonCookieDomain (cookie_domain): (null)
|
|
MellonCookiePath (cookie_path): (null)
|
|
MellonCond (cond): 0 items
|
|
MellonSetEnv (envattr): 0 items
|
|
MellonUser (userattr): NAME_ID
|
|
MellonIdP (idpattr): IDP
|
|
MellonSessionDump (dump_session): Off
|
|
MellonSamlResponseDump (dump_saml_response): Off
|
|
MellonEndpointPath (endpoint_path): /mellon/
|
|
MellonSPMetadataFile (sp_metadata_file):
|
|
pathname: "/etc/httpd/saml2/demo_sp_metadata.xml"
|
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
|
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
|
|
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
|
|
entityID="https://mellon.example.com/mellon/metadata">
|
|
<SPSSODescriptor
|
|
AuthnRequestsSigned="true"
|
|
WantAssertionsSigned="true"
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing">
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<KeyDescriptor use="encryption">
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
|
<AssertionConsumerService
|
|
index="0"
|
|
isDefault="true"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://mellon.example.com/mellon/postResponse" />
|
|
<AssertionConsumerService
|
|
index="1"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
|
|
Location="https://mellon.example.com/mellon/artifactResponse" />
|
|
<AssertionConsumerService
|
|
index="2"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS"
|
|
Location="https://mellon.example.com/mellon/paosResponse" />
|
|
</SPSSODescriptor>
|
|
</EntityDescriptor>
|
|
MellonSPPrivateKeyFile (sp_private_key_file):
|
|
pathname: "/etc/httpd/saml2/demo.key"
|
|
-----BEGIN PRIVATE KEY-----
|
|
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHUXILDtuMxyFP
|
|
6OW81hqfj9z+gC7sxR6U8bRPI4gFiNjkNF+4HMyrKtVtfwA5WJ1tJ4IaZbg4fGap
|
|
iCcWQ5tjjuZ7CpZ6XLekq63OGrkgZxNm8L+AjvREv78iR4Myc4x6ybN1LwQnV+oD
|
|
F0i9SAEPnfJCaCA+1+DC3RKy7+xtK3SVimUWwAHmkNU6N0wCVSNYn1KgnxBSCPTx
|
|
2DifbyRl21SiokCfLSnktE++WBzRzldSxzMrkSfFoS7/uT232tbdw2NsJmHGLRGk
|
|
myBrEC6BVhQ746NM1cLDtrOots7bNfZ3yfb3W1tpoKVOhM2se3OTKdidAQsaGlVu
|
|
7QIhBqinAgMBAAECggEBAJtU662WfJ9vqJRgCnpp2QG02iM0vl0jGbw1ybFLHXxC
|
|
s9TUxCv1tcNHdGEK8p++YaFpgskTsMfEmzVPuDZvpa+m9BO7op3ll/CrIp5W0SNh
|
|
cQtuX6/OuKrDTC9oz+QHjNk8S7DtXS1UJDkYckWg0cLb8qqx/z86eh0isKnmtLg2
|
|
H1+6L6mB9fcZldkcrU+kXT+dcDX85skMZAeBsrG4yaoX26AzVl8lEl2rJAQvpxj8
|
|
5wGBC4riWY6TzMYiCjcS5JfZIlbhcZe61ej3A48NVBSKCP1XKo0xbKuOHIQuMeeW
|
|
wSaboBwRzJ9JdTXlq5UWfLvmjXDc/HCwk/N7cj021uECgYEA5KkQr3cSKrMIkYoO
|
|
H0Vnkw1kYYGUjtTL00Nfdkv7uGMF122nyt1ND0gpdS0jgNx3LSEam/gY35UWEjGH
|
|
i8DGD04k8pvKDUsl8cuYPcC3oce1lLCGAnw+aHPC5wtA829CLOLtBfxXIhVAI0tp
|
|
ECosD/A63/m1LC19XolOd10/PC8CgYEA3yZChEYZupDGJFZltiy0ZgUarvD2Ss4N
|
|
QiRVR+CmpBrOKZdD8q6uUuqWQN9Rw7kXm8LxAPYwiIDVjxjYALF+j7/9Q1oZyKuv
|
|
eHJdMe4eRUeqeaIKbxnFfKwGZ5rj97jwPrkUCxio75KZhpOcDHMSgBCBtzW0XIZl
|
|
gTeQYOshZQkCgYB5TK6LRnEesabj/gaL1DejrMEJcMIsGvqdceocSSaZo/4fUA5o
|
|
8YjFiJRlkrJ403ttN1h0UOJxCReSQzASlQr8Z4n2IWrILotMf6Kdb7R6YAUVgac1
|
|
fk9k/bPw+OlVujmyshbmy/w1GmzRzFlJt/Vz5w50bnULoH4XPmOfspmvBQKBgBcJ
|
|
rihVzGY0eCBcQxfxuZYmxMB25BaI+1luwtcu3EVo9wvYMA2n9xtcWLLN23UncMaF
|
|
87ezswMEugeR+wrnSDezDISdkrfi8bSvqetzt/BTG8h+8DDUKk1avTaJCSwUDcmL
|
|
9gPHQfmp2uvH5X5riudpzNqLUtmSjnwurlszKzlxAoGAR8STlDJhNph+p3cF8k25
|
|
ydT1kypxnjzVG8CAV5/h3dUmc7j7gyV8NlWZfWacxMZWOBsrdVh0zhMNUPiLJaGd
|
|
I1isOkmiN9JFYMMhHSnhPnTCIjmu6uBLxf8wotHAvzWOJPV7lUZbw21KIN3DS79F
|
|
sGZ2QzGYn4inHG4UHClhZxU=
|
|
-----END PRIVATE KEY-----
|
|
MellonSPCertFile (sp_cert_file):
|
|
pathname: "/etc/httpd/saml2/demo.cert"
|
|
-----BEGIN CERTIFICATE-----
|
|
MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=
|
|
-----END CERTIFICATE-----
|
|
MellonIdPPublicKeyFile (idp_public_key_file):
|
|
file_data: NULL
|
|
MellonIdPCAFile (idp_ca_file):
|
|
file_data: NULL
|
|
MellonIdPMetadataFile (idp_metadata): 1 items
|
|
[ 0] Metadata
|
|
pathname: "/etc/httpd/saml2/demo_keycloak_ipa_idp_metadata.xml"
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!--
|
|
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
~ and other contributors as indicated by the @author tags.
|
|
~
|
|
~ 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.
|
|
-->
|
|
|
|
<EntitiesDescriptor Name="urn:keycloak" xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
|
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
|
|
<EntityDescriptor entityID="https://rhsso.example.com:8443/auth/realms/ipa">
|
|
<IDPSSODescriptor WantAuthnRequestsSigned="true"
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing">
|
|
<dsig:KeyInfo>
|
|
<dsig:KeyName>R2OGk9W0luNm_NtZbURWOrPlvFzSTDMimCVK5N1Mj5U</dsig:KeyName>
|
|
<dsig:X509Data>
|
|
<dsig:X509Certificate>MIIClTCCAX0CBgFeFdE9pDANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDDANpcGEwHhcNMTcwODI0MTk1NDQ3WhcNMjcwODI0MTk1NjI3WjAOMQwwCgYDVQQDDANpcGEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgIPeag+JJmhtAkIGBwUT/req+jKC6c0Vl1Ngtzbcd07CP9mq1DomBkjuWl59J2urlEfrV4yT8avia0eYE6Dm/TqC74SHt3TVtiUliynAh/z2JvFlLb/EbGePSKrMnuNV8rV75YGcyE12vBRooUPx3hGaygsfaSOg+BijDuCSpbVdWSdVx9VecsWJfxSochOZUj6yvm/qTb8Ptl0x/o7/b/16GgjFRIKSFrdk8pVtMn1wCzpQQoGVHZmp1jrppGcp8KXIK54q7b4pPiTzlW6xhBgrmW2RtWQesCmN8ga1CVeBZKLsaH7argwGH5Ttz31iensqUO0degFu6nwCltgTVAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFx8dl6RDle65q3IHIiGaL5fbJK5HxQiMXpk4N5riWQTP4g6xoTNAG4OFFUd4uRxt2ovdEdkbzhEy2lV4x626QdEfK5V9QKppupsTxTGA/4NMW9QCocAvFSpmYErmJIhfy6zzELoBK4Dpfcc3u1peHx2686msx6ExARF116d+5Xaps1dmPPy3yb2cCKzKbLhieqv+aLLrwz657ERUc4OnqEMEmmHFhHvPI7LRlS4AQ1/s1QlKcM9yqcu8WN3yKM/kuvZtZ0YTCSIl9W1b+I5v8wNoVFB22s7rfxs3DfJFaIImaTmRzaDX0MXgibEckrkigpO+anKe9B9z8CJdtlUHco=</dsig:X509Certificate>
|
|
</dsig:X509Data>
|
|
</dsig:KeyInfo>
|
|
</KeyDescriptor>
|
|
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
|
|
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleSignOnService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleSignOnService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
</IDPSSODescriptor>
|
|
</EntityDescriptor>
|
|
</EntitiesDescriptor>
|
|
[ 0] Chain File
|
|
file_data: NULL
|
|
MellonIdPIgnore (idp_ignore):
|
|
MellonSPentityId (sp_entity_id): (null)
|
|
MellonOrganizationName (sp_org_name): 0 items
|
|
MellonOrganizationDisplayName (sp_org_display_name): 0 items
|
|
MellonOrganizationURL (sp_org_url): 0 items
|
|
MellonSessionLength (session_length): -1
|
|
MellonNoCookieErrorPage (no_cookie_error_page): (null)
|
|
MellonNoSuccessErrorPage (no_success_error_page): (null)
|
|
MellonDefaultLoginPath (login_path): /
|
|
MellonDiscoveryURL (discovery_url): (null)
|
|
MellonProbeDiscoveryTimeout (probe_discovery_timeout): -1
|
|
MellonProbeDiscoveryIdP (probe_discovery_idp): 0 items
|
|
MellonAuthnContextClassRef (authn_context_class_ref): 0 items
|
|
MellonSubjectConfirmationDataAddressCheck (subject_confirmation_data_address_check): On
|
|
MellonDoNotVerifyLogoutSignature (do_not_verify_logout_signature): 0 items
|
|
MellonPostReplay (post_replay): On
|
|
MellonECPSendIDPList (ecp_send_idplist): On
|
|
enter function am_auth_mellon_user
|
|
enter function am_handle_login
|
|
Loading SP Metadata
|
|
pathname: "/etc/httpd/saml2/demo_sp_metadata.xml"
|
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
|
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
|
|
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
|
|
entityID="https://mellon.example.com/mellon/metadata">
|
|
<SPSSODescriptor
|
|
AuthnRequestsSigned="true"
|
|
WantAssertionsSigned="true"
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing">
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<KeyDescriptor use="encryption">
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
|
<AssertionConsumerService
|
|
index="0"
|
|
isDefault="true"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://mellon.example.com/mellon/postResponse" />
|
|
<AssertionConsumerService
|
|
index="1"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
|
|
Location="https://mellon.example.com/mellon/artifactResponse" />
|
|
<AssertionConsumerService
|
|
index="2"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS"
|
|
Location="https://mellon.example.com/mellon/paosResponse" />
|
|
</SPSSODescriptor>
|
|
</EntityDescriptor>
|
|
Loading IdP Metadata
|
|
pathname: "/etc/httpd/saml2/demo_keycloak_ipa_idp_metadata.xml"
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!--
|
|
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
~ and other contributors as indicated by the @author tags.
|
|
~
|
|
~ 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.
|
|
-->
|
|
|
|
<EntitiesDescriptor Name="urn:keycloak" xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
|
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
|
|
<EntityDescriptor entityID="https://rhsso.example.com:8443/auth/realms/ipa">
|
|
<IDPSSODescriptor WantAuthnRequestsSigned="true"
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing">
|
|
<dsig:KeyInfo>
|
|
<dsig:KeyName>R2OGk9W0luNm_NtZbURWOrPlvFzSTDMimCVK5N1Mj5U</dsig:KeyName>
|
|
<dsig:X509Data>
|
|
<dsig:X509Certificate>MIIClTCCAX0CBgFeFdE9pDANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDDANpcGEwHhcNMTcwODI0MTk1NDQ3WhcNMjcwODI0MTk1NjI3WjAOMQwwCgYDVQQDDANpcGEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgIPeag+JJmhtAkIGBwUT/req+jKC6c0Vl1Ngtzbcd07CP9mq1DomBkjuWl59J2urlEfrV4yT8avia0eYE6Dm/TqC74SHt3TVtiUliynAh/z2JvFlLb/EbGePSKrMnuNV8rV75YGcyE12vBRooUPx3hGaygsfaSOg+BijDuCSpbVdWSdVx9VecsWJfxSochOZUj6yvm/qTb8Ptl0x/o7/b/16GgjFRIKSFrdk8pVtMn1wCzpQQoGVHZmp1jrppGcp8KXIK54q7b4pPiTzlW6xhBgrmW2RtWQesCmN8ga1CVeBZKLsaH7argwGH5Ttz31iensqUO0degFu6nwCltgTVAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFx8dl6RDle65q3IHIiGaL5fbJK5HxQiMXpk4N5riWQTP4g6xoTNAG4OFFUd4uRxt2ovdEdkbzhEy2lV4x626QdEfK5V9QKppupsTxTGA/4NMW9QCocAvFSpmYErmJIhfy6zzELoBK4Dpfcc3u1peHx2686msx6ExARF116d+5Xaps1dmPPy3yb2cCKzKbLhieqv+aLLrwz657ERUc4OnqEMEmmHFhHvPI7LRlS4AQ1/s1QlKcM9yqcu8WN3yKM/kuvZtZ0YTCSIl9W1b+I5v8wNoVFB22s7rfxs3DfJFaIImaTmRzaDX0MXgibEckrkigpO+anKe9B9z8CJdtlUHco=</dsig:X509Certificate>
|
|
</dsig:X509Data>
|
|
</dsig:KeyInfo>
|
|
</KeyDescriptor>
|
|
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
|
|
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleSignOnService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleSignOnService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
</IDPSSODescriptor>
|
|
</EntityDescriptor>
|
|
</EntitiesDescriptor>
|
|
SAML AuthnRequest: http_method=LASSO_HTTP_METHOD_REDIRECT
|
|
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_A65FF17C0924D19BE0FEC241B49EA45C" Version="2.0" IssueInstant="2017-08-30T16:15:09Z" Destination="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" Consent="urn:oasis:names:tc:SAML:2.0:consent:current-implicit" SignType="0" SignMethod="0" ForceAuthn="false" IsPassive="false" AssertionConsumerServiceURL="https://mellon.example.com/mellon/postResponse">
|
|
<saml:Issuer>https://mellon.example.com/mellon/metadata</saml:Issuer>
|
|
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" AllowCreate="true"/>
|
|
</samlp:AuthnRequest>
|
|
|
|
=== Response ===
|
|
Status: 303 See Other(303)
|
|
user: (null) auth_type=(null)
|
|
Response Headers:
|
|
Cache-Control: private, max-age=0, must-revalidate
|
|
Set-Cookie: mellon-cookie=cookietest; Version=1; Path=/; Domain=mellon.example.com;
|
|
Location: https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml?SAMLRequest=hZLNbsIwEIRfJfIdnED4syBSSEBCohWCtodeKisswlJsp94NpW9fJ5SWXsrJ0nhHs99opyh1WYm0pqPZwnsNSMFZlwZF%2BzFjtTPCSlQojNSAggqxSx%2FWotcNReUs2cKW7Mbyv0MigiNlDQtW%2BYy9pcPBchmNsnDSi%2FNoMl%2BEy0XWi6N5PFmk8SBjwQs49PMz5u3ehFjDyiBJQ14Ko1EnHHf64VM0FNFAhJNXFuSeQRlJretIVKHg3B0RbRfOUlcldAurxTiO%2B1x6bu5Alhq5qiS%2FEvEGhQWZNQhN0n9MxWVIFLVz%2Fu0oH6EKRSxYWldAW%2B2MHWSJ0ABsfAfqBD9Keq2kCas1uB24kyrgebv%2BXV9DWVpzu%2F%2B3xCuLtAWsmiVYMm32Fm1LLrlv1kByL0lO%2Ba1vermJR0%2B6yjfWw3w2KFreKaJR1L5zaEcFOWlQ%2BUI8og%2F7yHzN5LHJ1cB4con8e3nJFw%3D%3D&RelayState=https%3A%2F%2Fmellon.example.com%2Fsaml-test%2Fprotected.html&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=gBd8iP4CvbWajeMQHKOMgc5NBx7i6Kf5gXcbSa54oehMXgpPJJuwlY8BLTH861vGnl7AxaO%2F2soJPai4D96aNowm8hr9FBokjvI%2FjwdEVtRiFlng18DpEXPTE1SAa4cuxWcLE3BAZD2HZ0sW%2F91sRGnymFH9lC4cDiU1pG9OBBI1pBYxjtrAM%2FHvEjDNZ0xYTwji8S6ltrM0bBFbTdftcn5YCwI31SAFVhopbPRTfiEhanTYChbjy7h%2Fp6BHTwfvcLw4Pud98phEIhXTdK4XIJGSN%2BmCYeXHQZPyGnRGZcmfmPrEcIpptT4a5xRkltfJPHUSLnI%2Ft9QsEuYm02%2F4%2BQ%3D%3D
|
|
Content-Length: 1318
|
|
Keep-Alive: timeout=5, max=99
|
|
Connection: Keep-Alive
|
|
Content-Type: text/html; charset=iso-8859-1
|
|
Response Error Headers:
|
|
Environment:
|
|
UNIQUE_ID: WabkjcTYa6iga7y800KGZgAAAAA
|
|
HTTPS: on
|
|
SSL_TLS_SNI: mellon.example.com
|
|
---------------------------------- New Request ---------------------------------
|
|
POST - /mellon/postResponse
|
|
log_id: (null)
|
|
server: name=/etc/httpd/conf.d/ssl.conf, scheme=https hostname=mellon.example.com port=443
|
|
pid: 21593, tid: 140251630954624
|
|
unparsed_uri: /mellon/postResponse
|
|
uri: /mellon/postResponse
|
|
path_info: /postResponse
|
|
filename: /var/www/html/mellon
|
|
query args: (null)
|
|
Request Headers:
|
|
Host: mellon.example.com
|
|
Connection: keep-alive
|
|
Content-Length: 15654
|
|
Cache-Control: max-age=0
|
|
Origin: https://rhsso.example.com:8443
|
|
Upgrade-Insecure-Requests: 1
|
|
User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36
|
|
Content-Type: application/x-www-form-urlencoded
|
|
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
|
|
DNT: 1
|
|
Referer: https://rhsso.example.com:8443/auth/realms/ipa/login-actions/authenticate?code=qv8kqt2kFiT0YBmG8TIzcNzgxfFp6q_N15M5pS931Eo.caa7c606-3404-4961-8af9-ba27345d1f7b&execution=10aa0b63-d5d9-4960-8ad8-16720df6fc8e
|
|
Accept-Encoding: gzip, deflate, br
|
|
Accept-Language: en-US,en;q=0.8
|
|
Cookie: mellon-cookie=cookietest
|
|
Mellon Directory Configuration for URL: /mellon/postResponse
|
|
MellonEnable (enable): info
|
|
MellonVariable (varname): cookie
|
|
MellonSecureCookie (secure): Off
|
|
MellonMergeEnvVars (merge_env_vars): (null)
|
|
MellonEnvVarsIndexStart (env_vars_index_start): -1
|
|
MellonEnvVarsSetCount (env_vars_count_in_n): On
|
|
MellonCookieDomain (cookie_domain): (null)
|
|
MellonCookiePath (cookie_path): (null)
|
|
MellonCond (cond): 0 items
|
|
MellonSetEnv (envattr): 0 items
|
|
MellonUser (userattr): NAME_ID
|
|
MellonIdP (idpattr): IDP
|
|
MellonSessionDump (dump_session): Off
|
|
MellonSamlResponseDump (dump_saml_response): Off
|
|
MellonEndpointPath (endpoint_path): /mellon/
|
|
MellonSPMetadataFile (sp_metadata_file):
|
|
pathname: "/etc/httpd/saml2/demo_sp_metadata.xml"
|
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
|
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
|
|
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
|
|
entityID="https://mellon.example.com/mellon/metadata">
|
|
<SPSSODescriptor
|
|
AuthnRequestsSigned="true"
|
|
WantAssertionsSigned="true"
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing">
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<KeyDescriptor use="encryption">
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
|
<AssertionConsumerService
|
|
index="0"
|
|
isDefault="true"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://mellon.example.com/mellon/postResponse" />
|
|
<AssertionConsumerService
|
|
index="1"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
|
|
Location="https://mellon.example.com/mellon/artifactResponse" />
|
|
<AssertionConsumerService
|
|
index="2"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS"
|
|
Location="https://mellon.example.com/mellon/paosResponse" />
|
|
</SPSSODescriptor>
|
|
</EntityDescriptor>
|
|
MellonSPPrivateKeyFile (sp_private_key_file):
|
|
pathname: "/etc/httpd/saml2/demo.key"
|
|
-----BEGIN PRIVATE KEY-----
|
|
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHUXILDtuMxyFP
|
|
6OW81hqfj9z+gC7sxR6U8bRPI4gFiNjkNF+4HMyrKtVtfwA5WJ1tJ4IaZbg4fGap
|
|
iCcWQ5tjjuZ7CpZ6XLekq63OGrkgZxNm8L+AjvREv78iR4Myc4x6ybN1LwQnV+oD
|
|
F0i9SAEPnfJCaCA+1+DC3RKy7+xtK3SVimUWwAHmkNU6N0wCVSNYn1KgnxBSCPTx
|
|
2DifbyRl21SiokCfLSnktE++WBzRzldSxzMrkSfFoS7/uT232tbdw2NsJmHGLRGk
|
|
myBrEC6BVhQ746NM1cLDtrOots7bNfZ3yfb3W1tpoKVOhM2se3OTKdidAQsaGlVu
|
|
7QIhBqinAgMBAAECggEBAJtU662WfJ9vqJRgCnpp2QG02iM0vl0jGbw1ybFLHXxC
|
|
s9TUxCv1tcNHdGEK8p++YaFpgskTsMfEmzVPuDZvpa+m9BO7op3ll/CrIp5W0SNh
|
|
cQtuX6/OuKrDTC9oz+QHjNk8S7DtXS1UJDkYckWg0cLb8qqx/z86eh0isKnmtLg2
|
|
H1+6L6mB9fcZldkcrU+kXT+dcDX85skMZAeBsrG4yaoX26AzVl8lEl2rJAQvpxj8
|
|
5wGBC4riWY6TzMYiCjcS5JfZIlbhcZe61ej3A48NVBSKCP1XKo0xbKuOHIQuMeeW
|
|
wSaboBwRzJ9JdTXlq5UWfLvmjXDc/HCwk/N7cj021uECgYEA5KkQr3cSKrMIkYoO
|
|
H0Vnkw1kYYGUjtTL00Nfdkv7uGMF122nyt1ND0gpdS0jgNx3LSEam/gY35UWEjGH
|
|
i8DGD04k8pvKDUsl8cuYPcC3oce1lLCGAnw+aHPC5wtA829CLOLtBfxXIhVAI0tp
|
|
ECosD/A63/m1LC19XolOd10/PC8CgYEA3yZChEYZupDGJFZltiy0ZgUarvD2Ss4N
|
|
QiRVR+CmpBrOKZdD8q6uUuqWQN9Rw7kXm8LxAPYwiIDVjxjYALF+j7/9Q1oZyKuv
|
|
eHJdMe4eRUeqeaIKbxnFfKwGZ5rj97jwPrkUCxio75KZhpOcDHMSgBCBtzW0XIZl
|
|
gTeQYOshZQkCgYB5TK6LRnEesabj/gaL1DejrMEJcMIsGvqdceocSSaZo/4fUA5o
|
|
8YjFiJRlkrJ403ttN1h0UOJxCReSQzASlQr8Z4n2IWrILotMf6Kdb7R6YAUVgac1
|
|
fk9k/bPw+OlVujmyshbmy/w1GmzRzFlJt/Vz5w50bnULoH4XPmOfspmvBQKBgBcJ
|
|
rihVzGY0eCBcQxfxuZYmxMB25BaI+1luwtcu3EVo9wvYMA2n9xtcWLLN23UncMaF
|
|
87ezswMEugeR+wrnSDezDISdkrfi8bSvqetzt/BTG8h+8DDUKk1avTaJCSwUDcmL
|
|
9gPHQfmp2uvH5X5riudpzNqLUtmSjnwurlszKzlxAoGAR8STlDJhNph+p3cF8k25
|
|
ydT1kypxnjzVG8CAV5/h3dUmc7j7gyV8NlWZfWacxMZWOBsrdVh0zhMNUPiLJaGd
|
|
I1isOkmiN9JFYMMhHSnhPnTCIjmu6uBLxf8wotHAvzWOJPV7lUZbw21KIN3DS79F
|
|
sGZ2QzGYn4inHG4UHClhZxU=
|
|
-----END PRIVATE KEY-----
|
|
MellonSPCertFile (sp_cert_file):
|
|
pathname: "/etc/httpd/saml2/demo.cert"
|
|
-----BEGIN CERTIFICATE-----
|
|
MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=
|
|
-----END CERTIFICATE-----
|
|
MellonIdPPublicKeyFile (idp_public_key_file):
|
|
file_data: NULL
|
|
MellonIdPCAFile (idp_ca_file):
|
|
file_data: NULL
|
|
MellonIdPMetadataFile (idp_metadata): 1 items
|
|
[ 0] Metadata
|
|
pathname: "/etc/httpd/saml2/demo_keycloak_ipa_idp_metadata.xml"
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!--
|
|
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
~ and other contributors as indicated by the @author tags.
|
|
~
|
|
~ 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.
|
|
-->
|
|
|
|
<EntitiesDescriptor Name="urn:keycloak" xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
|
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
|
|
<EntityDescriptor entityID="https://rhsso.example.com:8443/auth/realms/ipa">
|
|
<IDPSSODescriptor WantAuthnRequestsSigned="true"
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing">
|
|
<dsig:KeyInfo>
|
|
<dsig:KeyName>R2OGk9W0luNm_NtZbURWOrPlvFzSTDMimCVK5N1Mj5U</dsig:KeyName>
|
|
<dsig:X509Data>
|
|
<dsig:X509Certificate>MIIClTCCAX0CBgFeFdE9pDANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDDANpcGEwHhcNMTcwODI0MTk1NDQ3WhcNMjcwODI0MTk1NjI3WjAOMQwwCgYDVQQDDANpcGEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgIPeag+JJmhtAkIGBwUT/req+jKC6c0Vl1Ngtzbcd07CP9mq1DomBkjuWl59J2urlEfrV4yT8avia0eYE6Dm/TqC74SHt3TVtiUliynAh/z2JvFlLb/EbGePSKrMnuNV8rV75YGcyE12vBRooUPx3hGaygsfaSOg+BijDuCSpbVdWSdVx9VecsWJfxSochOZUj6yvm/qTb8Ptl0x/o7/b/16GgjFRIKSFrdk8pVtMn1wCzpQQoGVHZmp1jrppGcp8KXIK54q7b4pPiTzlW6xhBgrmW2RtWQesCmN8ga1CVeBZKLsaH7argwGH5Ttz31iensqUO0degFu6nwCltgTVAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFx8dl6RDle65q3IHIiGaL5fbJK5HxQiMXpk4N5riWQTP4g6xoTNAG4OFFUd4uRxt2ovdEdkbzhEy2lV4x626QdEfK5V9QKppupsTxTGA/4NMW9QCocAvFSpmYErmJIhfy6zzELoBK4Dpfcc3u1peHx2686msx6ExARF116d+5Xaps1dmPPy3yb2cCKzKbLhieqv+aLLrwz657ERUc4OnqEMEmmHFhHvPI7LRlS4AQ1/s1QlKcM9yqcu8WN3yKM/kuvZtZ0YTCSIl9W1b+I5v8wNoVFB22s7rfxs3DfJFaIImaTmRzaDX0MXgibEckrkigpO+anKe9B9z8CJdtlUHco=</dsig:X509Certificate>
|
|
</dsig:X509Data>
|
|
</dsig:KeyInfo>
|
|
</KeyDescriptor>
|
|
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
|
|
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleSignOnService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleSignOnService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
</IDPSSODescriptor>
|
|
</EntityDescriptor>
|
|
</EntitiesDescriptor>
|
|
[ 0] Chain File
|
|
file_data: NULL
|
|
MellonIdPIgnore (idp_ignore):
|
|
MellonSPentityId (sp_entity_id): (null)
|
|
MellonOrganizationName (sp_org_name): 0 items
|
|
MellonOrganizationDisplayName (sp_org_display_name): 0 items
|
|
MellonOrganizationURL (sp_org_url): 0 items
|
|
MellonSessionLength (session_length): -1
|
|
MellonNoCookieErrorPage (no_cookie_error_page): (null)
|
|
MellonNoSuccessErrorPage (no_success_error_page): (null)
|
|
MellonDefaultLoginPath (login_path): /
|
|
MellonDiscoveryURL (discovery_url): (null)
|
|
MellonProbeDiscoveryTimeout (probe_discovery_timeout): -1
|
|
MellonProbeDiscoveryIdP (probe_discovery_idp): 0 items
|
|
MellonAuthnContextClassRef (authn_context_class_ref): 0 items
|
|
MellonSubjectConfirmationDataAddressCheck (subject_confirmation_data_address_check): On
|
|
MellonDoNotVerifyLogoutSignature (do_not_verify_logout_signature): 0 items
|
|
MellonPostReplay (post_replay): On
|
|
MellonECPSendIDPList (ecp_send_idplist): On
|
|
enter function am_auth_mellon_user
|
|
enter function am_handle_post_reply
|
|
Loading SP Metadata
|
|
pathname: "/etc/httpd/saml2/demo_sp_metadata.xml"
|
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
|
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
|
|
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
|
|
entityID="https://mellon.example.com/mellon/metadata">
|
|
<SPSSODescriptor
|
|
AuthnRequestsSigned="true"
|
|
WantAssertionsSigned="true"
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing">
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<KeyDescriptor use="encryption">
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
|
<AssertionConsumerService
|
|
index="0"
|
|
isDefault="true"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://mellon.example.com/mellon/postResponse" />
|
|
<AssertionConsumerService
|
|
index="1"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
|
|
Location="https://mellon.example.com/mellon/artifactResponse" />
|
|
<AssertionConsumerService
|
|
index="2"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS"
|
|
Location="https://mellon.example.com/mellon/paosResponse" />
|
|
</SPSSODescriptor>
|
|
</EntityDescriptor>
|
|
Loading IdP Metadata
|
|
pathname: "/etc/httpd/saml2/demo_keycloak_ipa_idp_metadata.xml"
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!--
|
|
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
~ and other contributors as indicated by the @author tags.
|
|
~
|
|
~ 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.
|
|
-->
|
|
|
|
<EntitiesDescriptor Name="urn:keycloak" xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
|
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
|
|
<EntityDescriptor entityID="https://rhsso.example.com:8443/auth/realms/ipa">
|
|
<IDPSSODescriptor WantAuthnRequestsSigned="true"
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing">
|
|
<dsig:KeyInfo>
|
|
<dsig:KeyName>R2OGk9W0luNm_NtZbURWOrPlvFzSTDMimCVK5N1Mj5U</dsig:KeyName>
|
|
<dsig:X509Data>
|
|
<dsig:X509Certificate>MIIClTCCAX0CBgFeFdE9pDANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDDANpcGEwHhcNMTcwODI0MTk1NDQ3WhcNMjcwODI0MTk1NjI3WjAOMQwwCgYDVQQDDANpcGEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgIPeag+JJmhtAkIGBwUT/req+jKC6c0Vl1Ngtzbcd07CP9mq1DomBkjuWl59J2urlEfrV4yT8avia0eYE6Dm/TqC74SHt3TVtiUliynAh/z2JvFlLb/EbGePSKrMnuNV8rV75YGcyE12vBRooUPx3hGaygsfaSOg+BijDuCSpbVdWSdVx9VecsWJfxSochOZUj6yvm/qTb8Ptl0x/o7/b/16GgjFRIKSFrdk8pVtMn1wCzpQQoGVHZmp1jrppGcp8KXIK54q7b4pPiTzlW6xhBgrmW2RtWQesCmN8ga1CVeBZKLsaH7argwGH5Ttz31iensqUO0degFu6nwCltgTVAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFx8dl6RDle65q3IHIiGaL5fbJK5HxQiMXpk4N5riWQTP4g6xoTNAG4OFFUd4uRxt2ovdEdkbzhEy2lV4x626QdEfK5V9QKppupsTxTGA/4NMW9QCocAvFSpmYErmJIhfy6zzELoBK4Dpfcc3u1peHx2686msx6ExARF116d+5Xaps1dmPPy3yb2cCKzKbLhieqv+aLLrwz657ERUc4OnqEMEmmHFhHvPI7LRlS4AQ1/s1QlKcM9yqcu8WN3yKM/kuvZtZ0YTCSIl9W1b+I5v8wNoVFB22s7rfxs3DfJFaIImaTmRzaDX0MXgibEckrkigpO+anKe9B9z8CJdtlUHco=</dsig:X509Certificate>
|
|
</dsig:X509Data>
|
|
</dsig:KeyInfo>
|
|
</KeyDescriptor>
|
|
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
|
|
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleSignOnService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleSignOnService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
</IDPSSODescriptor>
|
|
</EntityDescriptor>
|
|
</EntitiesDescriptor>
|
|
SAMLResponse:
|
|
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" ID="ID_cd361c13-dc8b-48b6-bc26-4982b07bf772" InResponseTo="_A65FF17C0924D19BE0FEC241B49EA45C" Version="2.0" IssueInstant="2017-08-30T16:15:22.397Z" Destination="https://mellon.example.com/mellon/postResponse" SignType="0" SignMethod="0">
|
|
<saml:Issuer>https://rhsso.example.com:8443/auth/realms/ipa</saml:Issuer>
|
|
<samlp:Status>
|
|
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
|
|
</samlp:Status>
|
|
<saml:Assertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion" ID="ID_cf2298f8-981e-4c79-b173-cd3d8e43601b" IssueInstant="2017-08-30T16:15:22.396Z" Version="2.0">
|
|
<saml:Issuer>https://rhsso.example.com:8443/auth/realms/ipa</saml:Issuer>
|
|
<dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
|
|
<dsig:SignedInfo>
|
|
<dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
|
<dsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
|
|
<dsig:Reference URI="#ID_cf2298f8-981e-4c79-b173-cd3d8e43601b">
|
|
<dsig:Transforms>
|
|
<dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
|
<dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
|
</dsig:Transforms>
|
|
<dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
|
|
<dsig:DigestValue>8OlYuzdYW/pu0OoNp9XFxRi1EETiNMZkgUpWOUJ/dG8=</dsig:DigestValue>
|
|
</dsig:Reference>
|
|
</dsig:SignedInfo>
|
|
<dsig:SignatureValue>IuBZQ38BqtUc2Qbyy9BFj3x9BCfDQcoEoGFgOa//GFEwzOxunU9OxyZiod6cr1Z/0WgPeabX1GHJUwv//kf22FA8VLC1afErY4Yis9eUQUFUETyFRoFHjpou/rGz0NsEw4y8nTPN6p1je6jDM7Fo5cfSY8og6MY4rUdKOF2/rCCoFRJUC/UIFf8mUmOh8UIUNzPZqDc02Rw8nmGP2eHhHpWjDBalmzt+EL66tVqco3kRtQmPSIomkkJGh9vMGmHnu6n3k7I6SX8/h4bzuPurFB3eGhlxn9WKMQOdGphq4KKssij6yyZq2cM2fFLvZkrZSfLsDKjrpsf2YLC+Cmy5Ng==</dsig:SignatureValue>
|
|
<dsig:KeyInfo>
|
|
<dsig:KeyName>R2OGk9W0luNm_NtZbURWOrPlvFzSTDMimCVK5N1Mj5U</dsig:KeyName>
|
|
<dsig:X509Data>
|
|
<dsig:X509Certificate>MIIClTCCAX0CBgFeFdE9pDANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDDANpcGEwHhcNMTcwODI0MTk1NDQ3WhcNMjcwODI0MTk1NjI3WjAOMQwwCgYDVQQDDANpcGEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgIPeag+JJmhtAkIGBwUT/req+jKC6c0Vl1Ngtzbcd07CP9mq1DomBkjuWl59J2urlEfrV4yT8avia0eYE6Dm/TqC74SHt3TVtiUliynAh/z2JvFlLb/EbGePSKrMnuNV8rV75YGcyE12vBRooUPx3hGaygsfaSOg+BijDuCSpbVdWSdVx9VecsWJfxSochOZUj6yvm/qTb8Ptl0x/o7/b/16GgjFRIKSFrdk8pVtMn1wCzpQQoGVHZmp1jrppGcp8KXIK54q7b4pPiTzlW6xhBgrmW2RtWQesCmN8ga1CVeBZKLsaH7argwGH5Ttz31iensqUO0degFu6nwCltgTVAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFx8dl6RDle65q3IHIiGaL5fbJK5HxQiMXpk4N5riWQTP4g6xoTNAG4OFFUd4uRxt2ovdEdkbzhEy2lV4x626QdEfK5V9QKppupsTxTGA/4NMW9QCocAvFSpmYErmJIhfy6zzELoBK4Dpfcc3u1peHx2686msx6ExARF116d+5Xaps1dmPPy3yb2cCKzKbLhieqv+aLLrwz657ERUc4OnqEMEmmHFhHvPI7LRlS4AQ1/s1QlKcM9yqcu8WN3yKM/kuvZtZ0YTCSIl9W1b+I5v8wNoVFB22s7rfxs3DfJFaIImaTmRzaDX0MXgibEckrkigpO+anKe9B9z8CJdtlUHco=</dsig:X509Certificate>
|
|
</dsig:X509Data>
|
|
<dsig:KeyValue>
|
|
<dsig:RSAKeyValue>
|
|
<dsig:Modulus>oCD3moPiSZobQJCBgcFE/63qvoygunNFZdTYLc23HdOwj/ZqtQ6JgZI7lpefSdrq5RH61eMk/Gr4mtHmBOg5v06gu+Eh7d01bYlJYspwIf89ibxZS2/xGxnj0iqzJ7jVfK1e+WBnMhNdrwUaKFD8d4RmsoLH2kjoPgYow7gkqW1XVknVcfVXnLFiX8UqHITmVI+sr5v6k2/D7ZdMf6O/2/9ehoIxUSCkha3ZPKVbTJ9cAs6UEKBlR2ZqdY66aRnKfClyCueKu2+KT4k85VusYQYK5ltkbVkHrApjfIGtQlXgWSi7Gh+2q4MBh+U7c99Ynp7KlDtHXoBbup8ApbYE1Q==</dsig:Modulus>
|
|
<dsig:Exponent>AQAB</dsig:Exponent>
|
|
</dsig:RSAKeyValue>
|
|
</dsig:KeyValue>
|
|
</dsig:KeyInfo>
|
|
</dsig:Signature>
|
|
<saml:Subject>
|
|
<saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">G-e292fc24-74d9-4979-9f81-2c26d85174de</saml:NameID>
|
|
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
|
|
<saml:SubjectConfirmationData InResponseTo="_A65FF17C0924D19BE0FEC241B49EA45C" NotOnOrAfter="2017-08-30T16:20:20.396Z" Recipient="https://mellon.example.com/mellon/postResponse"/>
|
|
</saml:SubjectConfirmation>
|
|
</saml:Subject>
|
|
<saml:Conditions NotBefore="2017-08-30T16:15:20.396Z" NotOnOrAfter="2017-08-30T16:16:20.396Z">
|
|
<saml:AudienceRestriction>
|
|
<saml:Audience>https://mellon.example.com/mellon/metadata</saml:Audience>
|
|
</saml:AudienceRestriction>
|
|
</saml:Conditions>
|
|
<saml:AuthnStatement AuthnInstant="2017-08-30T16:15:22.397Z" SessionIndex="caa7c606-3404-4961-8af9-ba27345d1f7b">
|
|
<saml:AuthnContext>
|
|
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef>
|
|
</saml:AuthnContext>
|
|
</saml:AuthnStatement>
|
|
<saml:AttributeStatement>
|
|
<saml:Attribute FriendlyName="List of groups user is a member of" Name="groups" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
|
<saml:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">ipausers</saml:AttributeValue>
|
|
<saml:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">openstack-users</saml:AttributeValue>
|
|
</saml:Attribute>
|
|
<saml:Attribute Name="Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
|
<saml:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">view-profile</saml:AttributeValue>
|
|
</saml:Attribute>
|
|
<saml:Attribute Name="Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
|
<saml:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">uma_authorization</saml:AttributeValue>
|
|
</saml:Attribute>
|
|
<saml:Attribute Name="Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
|
<saml:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">manage-account</saml:AttributeValue>
|
|
</saml:Attribute>
|
|
</saml:AttributeStatement>
|
|
</saml:Assertion>
|
|
<saml:EncryptedAssertion>
|
|
<xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element">
|
|
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
|
|
<ds:KeyInfo>
|
|
<xenc:EncryptedKey>
|
|
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
|
|
<xenc:CipherData>
|
|
<xenc:CipherValue>m5GHJo1Za6Aejg0O7ZpCZleaNS45qzST8/0qFORoGjfLyNm0+lcquA7L2j/puCuVPWJ2jS4Y8P62iWYbhnATo7IPO3srpcfrAZaPtVlDKVp0ra8knx73h7NNIrbkWS63TZZNRh5OU5MgJRShHEpKq8fbRanRlq1iLODveKgw64W3XYr7vXbVT26/2NrrA7bkPLbK7YUyglmYDHN9PUbEKxKwQiBLnKNvaQgvBZaBPTzYTiBidM1Jllp/mj8QzfwiXCIAS/28iVmDCmjkSN6j33nDDLYU/Cq3rIGOWI8uQiw2oh2PlZi49T3400ffz2L9Tucdm/kjkTbhwWB3b5A1YQ==</xenc:CipherValue>
|
|
</xenc:CipherData>
|
|
</xenc:EncryptedKey>
|
|
</ds:KeyInfo>
|
|
<xenc:CipherData>
|
|
<xenc:CipherValue>9agVoiDjgNINUO8G9L+D2vodXqbGgFyWfz2qmHTMEZLqmacSqNsX4bzyS+jE1yA9PR4vZXJsc8JwyQrFAyKcokbJHlIbB+BSUHaqd/5qH6BbA+mt48Er9aExwwEC0IHloIo8pg5WuNZ38+RATP5OVw+du3ZUQ22GWv918YaEOb7i1n36eNYiP9Fv+fCR6jtRaZBqFf/vvROv6ye1dVfDOhhZfflVBbhRKUTgng1eFIxuz/+BG8v+QnN1Hzo+4OMIgDxb4LuS9LSgJBpAyb/nazSJ6Qzmi1DNj3Mp4co/1iMVTdshF1gAOUBm0DWxCnH7pMX48VLMOqbhR1YOQrDUsqPBf/wFFbJKItUXCHi8U29tJnUaDfjfOMA8RRsfZ9wZ8mt3xAmeR+13VcZWgvTYD4Cjw8dXmFqQ5D71HtBGaVJzd9YCxsEDEMAmtkyeLrkBDQmGb6Jl5kR2WV22ZZcz885aIGwUYpG7u7K54O5/Y1s7dtKq9B7rnDv2yhNwm2LSlF59irPPiqfevM7B8uNuMXe8MVDde10f+d+tGyn4MdP1cim94UVThq0IBciiz28NMQBiI+q8tPmgCAqn3cgRx7u1hWZGf8q+v0bh5Db1igKrXzCNbOpD8kCkKv1nQEckilp8/WZjCH9LC7cLDXHfKorAWcy2qr6g/9XMdQcISXFGs9CZksXIt7lQl1ZUGrDKT3ejuWl9+kOD/H/ryCru+CbNl8UvIkPpiXRtPlYoaddhOqdfPA5xDdRpEbxpLjRQEOYFF1Sygub1S300ZJiOKa9py9bbsSSexBLDaK7qCH5f+tJt6fCLUkb9Eq0NCbwNQ1BLgc7Uhvhtb9+V4sSH0FQb7RxO0BSmaG1ZESCmTkwOra1BUgIISBQWI1YauzgeczypP3yFBVRXCIMxuPqi74hwwxg36VUc9JqaiUqXt3BFuHEdVMzkOdYuQ8FK6vxl2iV37oiG8yNbf9a32H2yR3v3Mcpz9ybicUKNTjSCJNP4ixCc9/+O8FdHwVIV6GcrPhlTbxjRdih0tWodcGYNqWt65YBNYsyExpOW7bS/nVaov/hMmWCv9FSg8/KK/ipAQxz2E/9V+SH5fv0KLfTQaaSy13XYBINm3xNcatr8xz6WXNkmf8AeHxQq8bSl/sAOeQnjn5H2S0s014l3ZfZ84RI5rI2bY5k7xWbnoCFr6e1jcA6UeKHB4zqes9azGxZ4A48VND1lNFUKt5XSxADLQjEH0nGxZczJMeYzHkrVqiUgtlPVxgDjm7TxfJDJGPumprmRxU3MYY8fr9E+3CCwAz9WJOxFdu1G/4cEo6zkMHhSmDddmSGcGGALbMFlMD0g0/o+P8GQ3pVEXd88bUH0U1Joanp0mJ9Tu6gS5LatPhAvbD6ucWKDvHXqRKYWy/N7txfSBrYbWkPcZrGesH3bVd8uWMgH61yg30Uq+K4/L9u9Wdtlu92aM/NTjNERGyXdxp+ZYrM3MEthnW8Oygt3/XI8stzml+HmAFvoDgpjTpkbY3prdu5Y+2FMCZVrq/qskpbT3n9aLjLnJVASzZUzwy/SuqzikH45Rstdm1himRksdG9cg2CIpQktXlD5cLfkTCfBuUYlr+MHYjOu8WMBNCXDeNdRgC9v/M/bqalQtOfGYlkK9NPpB8Ky2cKtykWdLDWdefbzXHM1Y2LEl0+ms+b0oZYe//61u8uvsjn5OpQ5/aNTM+ztQ5OsEPzn0skAkJONz6rD3YSZJuEp8pWHHEZkT4pF7+0aXiEJZfOrWSJPM7NgAjXIK93qomjZjHl6s3JodJzdycFSWeLdQjrIatu2PKhm1cSlwfhVhuumh7hMnDOyTdWNTgO2QH+y0ahudAviKYzHRIS9ad2103sWByxpRH4vRtVRcCfWPmQhtygn/3Gd2wHc2owXW9neUBASQJrNUIi3uDklftVAZwhMRCm6nGU5u2R7ywH1K2Ey6JNBp88bh4gn9dybFzYjpj9Ds+sCkqnm4B2O80x307vvKcQ/O5AEzF9ONFD5aypOVXlI1IAMSGraBA0oWeBeE8J6wTB0W3BSvF5PhuJYewu6pxrR9WEykkhJzN59fuOgjz6piJbgTjKSD1LYf4/ev1MxkfPOj611CF7XhhuZW94/3i0SCFTdkJdTXS4oepqBEsVYlaWGCg6Sh4Hznavz+LkeR3Z5aDc4KJfa2jTESxmFkIFgSglDq8TA+1XwCZo2mze2SjpPLEt5ZiIpX4F+RHiPZqikzshzVAeHoKH5rGOUx9/os+Fbvt/EWdpLkeMDRAGC4ptx76wBfrPJlH3k4LDBy8O7iIuwkdQ/XuV74wZSneW+jqpN+oUX+UcCnP6Hu8lZW/7Ip61i2cG+uD1hv0W/YF/9pomBQ2rEQ0hJVElJFpzpz38HriUbRkPiZyn467xec3GFm+8f9XINX8bcf4gmauV8f1hdfESegw0+pMdYFE6a62sWLJixCdOiZbkmkYXRiO7Bow8cCHLj8WKHe8EaUWuVOrJGvw8z+k5cYY0Opg6wG8bKN3Aeg8NFxr5RC9RFKt+3sYza28uCma24G+yHVPl6b4X04+q28oS6EmxW20VTz+uQGjAKxwB64aNr4lj+dqY41ZgLPVtrcrUpNtdtiqMKyIlyMVkNh24xEjCSEJ9RFDs1K4/GJa+1v2eM9QPA5WsN4kMIx5AgS1MIgYIL98tMH3CbXOjQTcGL2RbJDiICUQgXXLNWe+dDWfE1Lc8TGIHRZ6GmrYgF5yQx7PL7y2ZQblMY6nqEKvNPXcbVCSHWu0B15ZfEh/tpcuPWIU04Jq3KuVeEzJ/l3OsE+1jb9j+87ZjON+bezmxv6MHeziSKVoI2GJO0KL/HPTI/5RAMBVDdO0AkgLpDiatnrBvCUFXsvTVZt+h+fqQtjoTxaMmdlsK071RHqk47/8jXx1uFfA8LNzZsdZzqrQJXqh0paLmx9Sngki+TRgPfCzdpU2RNYXqn5qvaEn2dMCWZrIUMCHnHbNNqc4M0YIw869Nq/d35Wc+BDYDdDstkYaVxIV0oQIHaFb0Ewb96383kRJCKC1Gl9NIMwlxC+uJruXN3ApkyP731Mwkq7RX8sv6NI5h3UYhEwrlmvtnNlQ0S01W7qhbMfuEULT2sHc/NvFSMCtZAa2ipU+tSiaBpmElpZGyKJByF2XrxQDly84koxKQIR+vg7tabaRKQL4aIJQclRj1ewVei4iTE8NMML+ys4sqHYuH63e6iO6lBt306j52lDNBIV0ErLpLc5gDKgpfn8PbKcxkMc8v8pqCnZ48MVseNSRgkWKP2y5K6sZ6j2aT1i7/WHl3q0X6y5gTvDKmhKHzdEXR7cAdAfNZouh60dfSpGuN0y4cDn8y7nvzzW5w2TfAFV1SvwaBjIKqKMM3o6ZlEasqvcn7SwWtmViPJtlXvYNnM5idT4mR+r5SqfOqF3AQjKVG6fkaKVrucmZtWxiLp93CHdv4zRafwXr9RePjgeR9ix9cnb3PH+qbGIxYLt13gYpwj7eC7kYWKkHbVw0QLf6zm8loXFvXcQhnYbDb0xZDJdoHkBSBiEyoEQcr4Ps86XQHOJX1ez4GQ5d+fuNTkzoI7mts5sV/HW6kfqd/FMfHYH5D//2hYaluwhHXNhMDqHP0o7vLcg3zgRkhNV/csWcA4Vp8v2e7RE+13oLmREbtRa8mZmqQilAWzTjQAsM8Rp2CcoJGfRrdnZCS3t3ukrSNqJEyHjcreIRee82U+hhrdRsoj6kyVlLuhfv3PiNHHO7ockdwKPW/DNxKGii4qUCpkhaSLnsepXCWDk3hZLsS52WEqmNwA2x1y+KYsMiHUh7kYv5iSYWRyjY/eAWAS/dDcdzg7W0JFiefOb4CiHZvLsfv96GOqu6tQB2pb6nkhVH2CMRsCiZK0OqhII+AmB2RMqpbxvw8l5Vml9G4y+VLTlhwIp92bZ8nHI7j3khqn8dUGf+ZHAInt7XujFlP/p9uy2oV3dEPTPVZGxuQJgfNbGYYF5pUNotp831FL4MA4sUdLXa114JrRo9bWnDOXBrR+04ZUtpfaBehmKxMIVufy81fe2g7heBd/yoeRAkZAw6oUaLcgAWcGAUdR/Ozy121yCdroeeLqbm2nPlsGwDYCSwl0UhZKpYTAs16vvyata55LRPWjsHNs0tPmYtZQk/IOaV5q61Wt2ehsuqXnGmEkgd7Dr5kOokGjV0PRpC1P9NQ88WWeS/MeMGX1e0Ac8FYkJxpNwcdlwBwaKIMrOTrmOfuEibORIzTlh9mJQ99pJoL+FrE0S6Ye6UjAuwixvAgo2rY1JzeXkGv+x9hxBwtYkgY17snKT3lgv6aJxX25rx44EfqLnkAKqI3P/ZCCzixMcdGYILxB/7JAIAaoSNloTqEDyHUdpVpY/4wPMvVajn2O0WPEyk6CQJbzesjuF63Tz1igMqRY0YdJu9J1xRPqOo3m//1fS1rW3pofMCPY1FUCLQShL346t7u0OijOjSq/z3pfdWJ6DuLPAgWO4iLjAew3Qsch/KcDrSayEmwKo0fHQJEQr/EqYSebmRxUDqNkewEoDt85qZcLMu9kofbJRx7yItS/9Gbii1xJV1v9FghE9uAz9KM2DBxlt2oN7JbxbJOMm/h5aLLHTZpw4vm//GpUlZVrZlNJhJNw2QeLgq+zawDOulgUpuU+/G46H0uejnb4UHo/jwdOpEXnY7T5Omm9g1YPS22nzCxA4ile1j0fouRXfPpDcFkKsiIOj8feXoZahJSuxCTSQLrfnPpoacqtPCXx9Ons4V47TN3MsQvv/JBUxXNUhJPTI2d+SfZWHaqg8FoiLWFfRE8h24lsckxwYB6t1o80s4sQfqzUOC3nMl2/t+9d8Wvd8aa/S01lucD1Uweg4X6znzF+uNBm22FPaXWGKJar1OJeWxwDi7gx9Skco+rXWPNr+EWW7gLFzYaFMUdCwS58bGoMR3YCM5UnKUlVgVrlJzIKY1MvRdd+e2li7+LVssNkh2uzLBIlRH329rGLbkdtoRJ+3w67D8enw60xvJuh/unfEAA/81CfN+VH10yV3RvHtCgd+eFeUCh4wB2EKGXHEzufuvhEzzqJuu+nJwaKwAYzJBM4T9QoxZzmM5MUmqfc9zhaWWzYty+oBrca79lp+CL64EB+TLIKxf7WWt12aSHye9rNrSxSnkGR2b+plQWKMxN4lQWX0CgZDqim9BuItWgBNWUwMFwg9U0VZ6v+B3uNcAhkQJVSHurCY/ADkhkqU+j2HnNGupwAYNZv9W5/UuAD8yFpuP+JhtnTz+TGQzuy+B/cZcibZhFG2i5bAqrjxPGJQT/JNxQt8WkipdQfUdCNFhdh4HwD44RxKtBenpR51XXo5cbaQlhETFmaZzED9qf73OI5N6bPFv30WcqZpWEerWVT9hz5OuwTkIqKvtQgzBd/4qaAbMdeYb2F/eTxytKWYGbnarCcrasdkQS5IJfLYb2KyTm3hMc3EM+3/kF5OGszQQ1EaPQcsyI7GVmogRfNbitQ+qPTDjGJnotwwc5aLJpIa8pVeiFFCBfsEdqA5qIbS2NBc0A/Uv8e53L+fZy0uPpZfq4F7GO+qU/efa0+aVvW/aHJcyFJXvQHb2h0XjP7ljbfQB/5ypcP5cXS12at60w4hs7oJDfcQ30JHmeMIiZ9t2+bQwOn+M22KiVIHbjNRGUPfs1jwu5Cid69pqcRtSg2fxfpAH4h5B5PHybmeo2Q5kMMS1FS2ZUirwwfY9fk+q0pSLwq5fMfUooVxPXBgqtPYY4hMWU6A8a9cbUNsJZBSZi5mP1+1xRGAQ62xUCqOgGJt922/5YI2QNf9cWcKuFlsD2+RYLNgFHZK7OzCns8t2VaQZw/6rFURZKW+wfDY+bzYjmn/FgLHOGp5YxBhzwvIcOEAltqC3wWF6c2ehnZGUH3E+JVvaB8mDG1bWf9Gxby9cjKSIUcIS1CTxfboSSx3yYhr8qONLsYKkNZoVnAHks33M5RduRv8XVo51PnqVp7GENpyy2Q3tmQoGAhLz401vI3jhDGhXB7TFqCnQfN4VDnb3z7WuFVGz8P4iMdlIs7eDOM0NF3TgwFxoK+QdQh2DYP1f7hx6kXXON+/Bwo1II8VewMBPyS+/vRbD+zihEoVtuEG0k0h1oyfXuavmkzCgXr17efq+J8FC7FRT4npwUbqSyEOGW1fXtGYqUGeirL3SVGshmehujovVTKkJ0g8Vy/t5i5JKGXxxfhKxH151IrTIZ5oyDbL3ZbJ+b0OrgOS4HDPDBKB5RYqv8N5s8Ylnk0piKrk3nvnYA6j1V7Xu+HvwmfdrdpTcfWFMmy6K5cmxZWQmmS6uNUWBrfa303uMJmAjoZy9U/9qg1H/G+/TcTF7FhUZ+FdAUUGIns94Pjl1D+qeXA61TDRLtV40QHyKgcGXO0GBMBlOjIxdhNDdDMoqt9+xFoAml8Ue89hCYeDXDtPg+/T8a+/C+5CQ5FkD7ZEPAvaEYYeWUGC/HPAdVohtjnhTIigCqsil6+AxOFKaxV1R3Y2H35X3QDnCLow5MNfb0ck+7RtkOhIMqaDLWbF4/OcmNuW91Jchk6INIzLiwZnlSrBIK8He9SrhoE0Tz4+5dAqdvXCZu8IkWg31fxsLDutI9Fa0iFqaSrda/YVIEyp8qlMy2V3GEsOjhX/sPth4YAhTg2SgPQ+ncGrUCHtTCMpNJMqScJbeIWX2NWLsLOiSALc6WCQgALbm+AkpXFxCrxBcX77gENU7bMiSOqW45k1bHj0iPS737CMQ8KRMmdhZb+KNIbgk5HJZRxhPNWIQEub5tjyIxw8TiPN0IXsS+pLcTWFur1I11nplJMdIaho6OOycn/ww6uMsU/yTvBLDPTtHKK4ZVQIr4abDySfX915cjfGx61pTsH5Hs8hDFoqmUh3UUr/8NF9aMpuqZhuOYq2hi5DvIMiS8HQYGzW4GO4wE4fP2/nRZXecYOvVQi+FWTKwXtA3OduMotKj29QgCvRYXMRIyXkz4Mh+UvfUlEYtvy9NZaNboHTtoIJemQ2LCakIFxp0zk69sMsFm5c3hBgCxIXKVmJNCrO565/VA1kuP1qoJhekxBvyo85qSJfjCE4UsX8HcD+HXZqmYDkfbskcLwQkIzYLQus8+oWtRSIrOr1iGR1vTktq1WtRVZ+Af+alslzBZLOBcaNqx0XZRBdjZ4m2pSvlKihSn/9Za0iASX/oQcUyQ2xV6Bw843wONbEqB8ulXnpLI2RVvSdzBpj+yopD+f9TXZJf/qyNNa0sb+q/VTcG60I9xJ+S/pFnS/zIlHajuaS2heekN36nNP9i9q2nrBjMRb6bMF/sL/VBTACIsBxVaI5X1buB+8GqyGhUI0mbohmA5EnM7xOkcwGEdAi9pT9Zku1KWyk2g1nNbml1Q=</xenc:CipherValue>
|
|
</xenc:CipherData>
|
|
</xenc:EncryptedData>
|
|
</saml:EncryptedAssertion>
|
|
</samlp:Response>
|
|
am_new_request_session id=9cf3ebac4e542827e276dc064ce8c4e4 cookie_token="Name='mellon-cookie' Domain='mellon.example.com' Path='/'"
|
|
am_cache_new created new session, id=9cf3ebac4e542827e276dc064ce8c4e4 at 2017-08-30T16:15:23Z cookie_token="Name='mellon-cookie' Domain='mellon.example.com' Path='/'"
|
|
am_handle_session_expire failed to find Assertion.AuthnStatement.SessionNotOnOrAfter
|
|
add_attributes name=groups value=ipausers
|
|
add_attributes name=groups value=openstack-users
|
|
add_attributes name=Role value=view-profile
|
|
add_attributes name=Role value=uma_authorization
|
|
add_attributes name=Role value=manage-account
|
|
[APLOG_DEBUG auth_mellon_handler.c:549] The current LassoProfile object doesn't contain a LassoIdentity object.
|
|
=== Response ===
|
|
Status: 303 See Other(303)
|
|
user: (null) auth_type=(null)
|
|
Response Headers:
|
|
Cache-Control: private, max-age=0, must-revalidate
|
|
Set-Cookie: mellon-cookie=9cf3ebac4e542827e276dc064ce8c4e4; Version=1; Path=/; Domain=mellon.example.com;
|
|
Location: https://mellon.example.com/saml-test/protected.html
|
|
Content-Length: 258
|
|
Keep-Alive: timeout=5, max=100
|
|
Connection: Keep-Alive
|
|
Content-Type: text/html; charset=iso-8859-1
|
|
Response Error Headers:
|
|
Environment:
|
|
UNIQUE_ID: Wabkm2fzHRm5EyVgPZnqEAAAAAU
|
|
HTTPS: on
|
|
SSL_TLS_SNI: mellon.example.com
|
|
---------------------------------- New Request ---------------------------------
|
|
GET - /saml-test/protected.html
|
|
log_id: (null)
|
|
server: name=/etc/httpd/conf.d/ssl.conf, scheme=https hostname=mellon.example.com port=443
|
|
pid: 21593, tid: 140251630954624
|
|
unparsed_uri: /saml-test/protected.html
|
|
uri: /saml-test/protected.html
|
|
path_info:
|
|
filename: /var/www/html/saml-test/protected.html
|
|
query args: (null)
|
|
Request Headers:
|
|
Host: mellon.example.com
|
|
Connection: keep-alive
|
|
Cache-Control: max-age=0
|
|
Upgrade-Insecure-Requests: 1
|
|
User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36
|
|
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
|
|
DNT: 1
|
|
Referer: https://rhsso.example.com:8443/auth/realms/ipa/login-actions/authenticate?code=qv8kqt2kFiT0YBmG8TIzcNzgxfFp6q_N15M5pS931Eo.caa7c606-3404-4961-8af9-ba27345d1f7b&execution=10aa0b63-d5d9-4960-8ad8-16720df6fc8e
|
|
Accept-Encoding: gzip, deflate, br
|
|
Accept-Language: en-US,en;q=0.8
|
|
Cookie: mellon-cookie=9cf3ebac4e542827e276dc064ce8c4e4
|
|
Mellon Directory Configuration for URL: /saml-test/protected.html
|
|
MellonEnable (enable): auth
|
|
MellonVariable (varname): cookie
|
|
MellonSecureCookie (secure): Off
|
|
MellonMergeEnvVars (merge_env_vars): (null)
|
|
MellonEnvVarsIndexStart (env_vars_index_start): -1
|
|
MellonEnvVarsSetCount (env_vars_count_in_n): On
|
|
MellonCookieDomain (cookie_domain): (null)
|
|
MellonCookiePath (cookie_path): (null)
|
|
MellonCond (cond): 0 items
|
|
MellonSetEnv (envattr): 0 items
|
|
MellonUser (userattr): NAME_ID
|
|
MellonIdP (idpattr): IDP
|
|
MellonSessionDump (dump_session): Off
|
|
MellonSamlResponseDump (dump_saml_response): Off
|
|
MellonEndpointPath (endpoint_path): /mellon/
|
|
MellonSPMetadataFile (sp_metadata_file):
|
|
pathname: "/etc/httpd/saml2/demo_sp_metadata.xml"
|
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
|
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
|
|
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
|
|
entityID="https://mellon.example.com/mellon/metadata">
|
|
<SPSSODescriptor
|
|
AuthnRequestsSigned="true"
|
|
WantAssertionsSigned="true"
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing">
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<KeyDescriptor use="encryption">
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
|
<AssertionConsumerService
|
|
index="0"
|
|
isDefault="true"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://mellon.example.com/mellon/postResponse" />
|
|
<AssertionConsumerService
|
|
index="1"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
|
|
Location="https://mellon.example.com/mellon/artifactResponse" />
|
|
<AssertionConsumerService
|
|
index="2"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS"
|
|
Location="https://mellon.example.com/mellon/paosResponse" />
|
|
</SPSSODescriptor>
|
|
</EntityDescriptor>
|
|
MellonSPPrivateKeyFile (sp_private_key_file):
|
|
pathname: "/etc/httpd/saml2/demo.key"
|
|
-----BEGIN PRIVATE KEY-----
|
|
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHUXILDtuMxyFP
|
|
6OW81hqfj9z+gC7sxR6U8bRPI4gFiNjkNF+4HMyrKtVtfwA5WJ1tJ4IaZbg4fGap
|
|
iCcWQ5tjjuZ7CpZ6XLekq63OGrkgZxNm8L+AjvREv78iR4Myc4x6ybN1LwQnV+oD
|
|
F0i9SAEPnfJCaCA+1+DC3RKy7+xtK3SVimUWwAHmkNU6N0wCVSNYn1KgnxBSCPTx
|
|
2DifbyRl21SiokCfLSnktE++WBzRzldSxzMrkSfFoS7/uT232tbdw2NsJmHGLRGk
|
|
myBrEC6BVhQ746NM1cLDtrOots7bNfZ3yfb3W1tpoKVOhM2se3OTKdidAQsaGlVu
|
|
7QIhBqinAgMBAAECggEBAJtU662WfJ9vqJRgCnpp2QG02iM0vl0jGbw1ybFLHXxC
|
|
s9TUxCv1tcNHdGEK8p++YaFpgskTsMfEmzVPuDZvpa+m9BO7op3ll/CrIp5W0SNh
|
|
cQtuX6/OuKrDTC9oz+QHjNk8S7DtXS1UJDkYckWg0cLb8qqx/z86eh0isKnmtLg2
|
|
H1+6L6mB9fcZldkcrU+kXT+dcDX85skMZAeBsrG4yaoX26AzVl8lEl2rJAQvpxj8
|
|
5wGBC4riWY6TzMYiCjcS5JfZIlbhcZe61ej3A48NVBSKCP1XKo0xbKuOHIQuMeeW
|
|
wSaboBwRzJ9JdTXlq5UWfLvmjXDc/HCwk/N7cj021uECgYEA5KkQr3cSKrMIkYoO
|
|
H0Vnkw1kYYGUjtTL00Nfdkv7uGMF122nyt1ND0gpdS0jgNx3LSEam/gY35UWEjGH
|
|
i8DGD04k8pvKDUsl8cuYPcC3oce1lLCGAnw+aHPC5wtA829CLOLtBfxXIhVAI0tp
|
|
ECosD/A63/m1LC19XolOd10/PC8CgYEA3yZChEYZupDGJFZltiy0ZgUarvD2Ss4N
|
|
QiRVR+CmpBrOKZdD8q6uUuqWQN9Rw7kXm8LxAPYwiIDVjxjYALF+j7/9Q1oZyKuv
|
|
eHJdMe4eRUeqeaIKbxnFfKwGZ5rj97jwPrkUCxio75KZhpOcDHMSgBCBtzW0XIZl
|
|
gTeQYOshZQkCgYB5TK6LRnEesabj/gaL1DejrMEJcMIsGvqdceocSSaZo/4fUA5o
|
|
8YjFiJRlkrJ403ttN1h0UOJxCReSQzASlQr8Z4n2IWrILotMf6Kdb7R6YAUVgac1
|
|
fk9k/bPw+OlVujmyshbmy/w1GmzRzFlJt/Vz5w50bnULoH4XPmOfspmvBQKBgBcJ
|
|
rihVzGY0eCBcQxfxuZYmxMB25BaI+1luwtcu3EVo9wvYMA2n9xtcWLLN23UncMaF
|
|
87ezswMEugeR+wrnSDezDISdkrfi8bSvqetzt/BTG8h+8DDUKk1avTaJCSwUDcmL
|
|
9gPHQfmp2uvH5X5riudpzNqLUtmSjnwurlszKzlxAoGAR8STlDJhNph+p3cF8k25
|
|
ydT1kypxnjzVG8CAV5/h3dUmc7j7gyV8NlWZfWacxMZWOBsrdVh0zhMNUPiLJaGd
|
|
I1isOkmiN9JFYMMhHSnhPnTCIjmu6uBLxf8wotHAvzWOJPV7lUZbw21KIN3DS79F
|
|
sGZ2QzGYn4inHG4UHClhZxU=
|
|
-----END PRIVATE KEY-----
|
|
MellonSPCertFile (sp_cert_file):
|
|
pathname: "/etc/httpd/saml2/demo.cert"
|
|
-----BEGIN CERTIFICATE-----
|
|
MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=
|
|
-----END CERTIFICATE-----
|
|
MellonIdPPublicKeyFile (idp_public_key_file):
|
|
file_data: NULL
|
|
MellonIdPCAFile (idp_ca_file):
|
|
file_data: NULL
|
|
MellonIdPMetadataFile (idp_metadata): 1 items
|
|
[ 0] Metadata
|
|
pathname: "/etc/httpd/saml2/demo_keycloak_ipa_idp_metadata.xml"
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!--
|
|
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
~ and other contributors as indicated by the @author tags.
|
|
~
|
|
~ 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.
|
|
-->
|
|
|
|
<EntitiesDescriptor Name="urn:keycloak" xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
|
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
|
|
<EntityDescriptor entityID="https://rhsso.example.com:8443/auth/realms/ipa">
|
|
<IDPSSODescriptor WantAuthnRequestsSigned="true"
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing">
|
|
<dsig:KeyInfo>
|
|
<dsig:KeyName>R2OGk9W0luNm_NtZbURWOrPlvFzSTDMimCVK5N1Mj5U</dsig:KeyName>
|
|
<dsig:X509Data>
|
|
<dsig:X509Certificate>MIIClTCCAX0CBgFeFdE9pDANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDDANpcGEwHhcNMTcwODI0MTk1NDQ3WhcNMjcwODI0MTk1NjI3WjAOMQwwCgYDVQQDDANpcGEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgIPeag+JJmhtAkIGBwUT/req+jKC6c0Vl1Ngtzbcd07CP9mq1DomBkjuWl59J2urlEfrV4yT8avia0eYE6Dm/TqC74SHt3TVtiUliynAh/z2JvFlLb/EbGePSKrMnuNV8rV75YGcyE12vBRooUPx3hGaygsfaSOg+BijDuCSpbVdWSdVx9VecsWJfxSochOZUj6yvm/qTb8Ptl0x/o7/b/16GgjFRIKSFrdk8pVtMn1wCzpQQoGVHZmp1jrppGcp8KXIK54q7b4pPiTzlW6xhBgrmW2RtWQesCmN8ga1CVeBZKLsaH7argwGH5Ttz31iensqUO0degFu6nwCltgTVAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFx8dl6RDle65q3IHIiGaL5fbJK5HxQiMXpk4N5riWQTP4g6xoTNAG4OFFUd4uRxt2ovdEdkbzhEy2lV4x626QdEfK5V9QKppupsTxTGA/4NMW9QCocAvFSpmYErmJIhfy6zzELoBK4Dpfcc3u1peHx2686msx6ExARF116d+5Xaps1dmPPy3yb2cCKzKbLhieqv+aLLrwz657ERUc4OnqEMEmmHFhHvPI7LRlS4AQ1/s1QlKcM9yqcu8WN3yKM/kuvZtZ0YTCSIl9W1b+I5v8wNoVFB22s7rfxs3DfJFaIImaTmRzaDX0MXgibEckrkigpO+anKe9B9z8CJdtlUHco=</dsig:X509Certificate>
|
|
</dsig:X509Data>
|
|
</dsig:KeyInfo>
|
|
</KeyDescriptor>
|
|
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
|
|
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleSignOnService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleSignOnService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
</IDPSSODescriptor>
|
|
</EntityDescriptor>
|
|
</EntitiesDescriptor>
|
|
[ 0] Chain File
|
|
file_data: NULL
|
|
MellonIdPIgnore (idp_ignore):
|
|
MellonSPentityId (sp_entity_id): (null)
|
|
MellonOrganizationName (sp_org_name): 0 items
|
|
MellonOrganizationDisplayName (sp_org_display_name): 0 items
|
|
MellonOrganizationURL (sp_org_url): 0 items
|
|
MellonSessionLength (session_length): -1
|
|
MellonNoCookieErrorPage (no_cookie_error_page): (null)
|
|
MellonNoSuccessErrorPage (no_success_error_page): (null)
|
|
MellonDefaultLoginPath (login_path): /
|
|
MellonDiscoveryURL (discovery_url): (null)
|
|
MellonProbeDiscoveryTimeout (probe_discovery_timeout): -1
|
|
MellonProbeDiscoveryIdP (probe_discovery_idp): 0 items
|
|
MellonAuthnContextClassRef (authn_context_class_ref): 0 items
|
|
MellonSubjectConfirmationDataAddressCheck (subject_confirmation_data_address_check): On
|
|
MellonDoNotVerifyLogoutSignature (do_not_verify_logout_signature): 0 items
|
|
MellonPostReplay (post_replay): On
|
|
MellonECPSendIDPList (ecp_send_idplist): On
|
|
enter function am_auth_mellon_user
|
|
searching for session with key 9cf3ebac4e542827e276dc064ce8c4e4 (session) ... found.
|
|
Session Cache Entry
|
|
key: 9cf3ebac4e542827e276dc064ce8c4e4
|
|
name_id: G-e292fc24-74d9-4979-9f81-2c26d85174de
|
|
expires: 2017-08-31T16:15:23Z
|
|
access: 2017-08-30T16:15:23Z
|
|
logged_in: True
|
|
am_auth_mellon_user am_enable_auth, have valid session
|
|
am_check_permissions succeeds
|
|
|
|
=== Response ===
|
|
Status: 200 OK(200)
|
|
user: G-e292fc24-74d9-4979-9f81-2c26d85174de auth_type=Mellon
|
|
Response Headers:
|
|
Cache-Control: private, max-age=0, must-revalidate
|
|
Last-Modified: Mon, 28 Aug 2017 15:15:18 GMT
|
|
ETag: "4a-557d1c33a4519"
|
|
Accept-Ranges: bytes
|
|
Content-Length: 74
|
|
Keep-Alive: timeout=5, max=99
|
|
Connection: Keep-Alive
|
|
Content-Type: text/html; charset=UTF-8
|
|
Response Error Headers:
|
|
Cache-Control: private, max-age=0, must-revalidate
|
|
Environment:
|
|
UNIQUE_ID: Wabkm2fzHRm5EyVgPZnqEQAAAAU
|
|
MELLON_NAME_ID: G-e292fc24-74d9-4979-9f81-2c26d85174de
|
|
MELLON_NAME_ID_0: G-e292fc24-74d9-4979-9f81-2c26d85174de
|
|
MELLON_groups: ipausers
|
|
MELLON_groups_0: ipausers
|
|
MELLON_groups_1: openstack-users
|
|
MELLON_Role: view-profile
|
|
MELLON_Role_0: view-profile
|
|
MELLON_Role_1: uma_authorization
|
|
MELLON_Role_2: manage-account
|
|
MELLON_IDP: https://rhsso.example.com:8443/auth/realms/ipa
|
|
MELLON_IDP_0: https://rhsso.example.com:8443/auth/realms/ipa
|
|
HTTPS: on
|
|
SSL_TLS_SNI: mellon.example.com
|
|
---------------------------------- New Request ---------------------------------
|
|
GET - /favicon.ico
|
|
log_id: (null)
|
|
server: name=/etc/httpd/conf.d/ssl.conf, scheme=https hostname=mellon.example.com port=443
|
|
pid: 21593, tid: 140251630954624
|
|
unparsed_uri: /favicon.ico
|
|
uri: /favicon.ico
|
|
path_info:
|
|
filename: /var/www/html/favicon.ico
|
|
query args: (null)
|
|
Request Headers:
|
|
Host: mellon.example.com
|
|
Connection: keep-alive
|
|
User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36
|
|
Accept: image/webp,image/apng,image/*,*/*;q=0.8
|
|
DNT: 1
|
|
Referer: https://mellon.example.com/saml-test/protected.html
|
|
Accept-Encoding: gzip, deflate, br
|
|
Accept-Language: en-US,en;q=0.8
|
|
Cookie: mellon-cookie=9cf3ebac4e542827e276dc064ce8c4e4
|
|
Mellon Directory Configuration for URL: /favicon.ico
|
|
MellonEnable (enable): info
|
|
MellonVariable (varname): cookie
|
|
MellonSecureCookie (secure): Off
|
|
MellonMergeEnvVars (merge_env_vars): (null)
|
|
MellonEnvVarsIndexStart (env_vars_index_start): -1
|
|
MellonEnvVarsSetCount (env_vars_count_in_n): On
|
|
MellonCookieDomain (cookie_domain): (null)
|
|
MellonCookiePath (cookie_path): (null)
|
|
MellonCond (cond): 0 items
|
|
MellonSetEnv (envattr): 0 items
|
|
MellonUser (userattr): NAME_ID
|
|
MellonIdP (idpattr): IDP
|
|
MellonSessionDump (dump_session): Off
|
|
MellonSamlResponseDump (dump_saml_response): Off
|
|
MellonEndpointPath (endpoint_path): /mellon/
|
|
MellonSPMetadataFile (sp_metadata_file):
|
|
pathname: "/etc/httpd/saml2/demo_sp_metadata.xml"
|
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
|
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
|
|
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
|
|
entityID="https://mellon.example.com/mellon/metadata">
|
|
<SPSSODescriptor
|
|
AuthnRequestsSigned="true"
|
|
WantAssertionsSigned="true"
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing">
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<KeyDescriptor use="encryption">
|
|
<ds:KeyInfo>
|
|
<ds:X509Data>
|
|
<ds:X509Certificate>MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=</ds:X509Certificate>
|
|
</ds:X509Data>
|
|
</ds:KeyInfo>
|
|
</KeyDescriptor>
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://mellon.example.com/mellon/logout" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
|
<AssertionConsumerService
|
|
index="0"
|
|
isDefault="true"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://mellon.example.com/mellon/postResponse" />
|
|
<AssertionConsumerService
|
|
index="1"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
|
|
Location="https://mellon.example.com/mellon/artifactResponse" />
|
|
<AssertionConsumerService
|
|
index="2"
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS"
|
|
Location="https://mellon.example.com/mellon/paosResponse" />
|
|
</SPSSODescriptor>
|
|
</EntityDescriptor>
|
|
MellonSPPrivateKeyFile (sp_private_key_file):
|
|
pathname: "/etc/httpd/saml2/demo.key"
|
|
-----BEGIN PRIVATE KEY-----
|
|
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHUXILDtuMxyFP
|
|
6OW81hqfj9z+gC7sxR6U8bRPI4gFiNjkNF+4HMyrKtVtfwA5WJ1tJ4IaZbg4fGap
|
|
iCcWQ5tjjuZ7CpZ6XLekq63OGrkgZxNm8L+AjvREv78iR4Myc4x6ybN1LwQnV+oD
|
|
F0i9SAEPnfJCaCA+1+DC3RKy7+xtK3SVimUWwAHmkNU6N0wCVSNYn1KgnxBSCPTx
|
|
2DifbyRl21SiokCfLSnktE++WBzRzldSxzMrkSfFoS7/uT232tbdw2NsJmHGLRGk
|
|
myBrEC6BVhQ746NM1cLDtrOots7bNfZ3yfb3W1tpoKVOhM2se3OTKdidAQsaGlVu
|
|
7QIhBqinAgMBAAECggEBAJtU662WfJ9vqJRgCnpp2QG02iM0vl0jGbw1ybFLHXxC
|
|
s9TUxCv1tcNHdGEK8p++YaFpgskTsMfEmzVPuDZvpa+m9BO7op3ll/CrIp5W0SNh
|
|
cQtuX6/OuKrDTC9oz+QHjNk8S7DtXS1UJDkYckWg0cLb8qqx/z86eh0isKnmtLg2
|
|
H1+6L6mB9fcZldkcrU+kXT+dcDX85skMZAeBsrG4yaoX26AzVl8lEl2rJAQvpxj8
|
|
5wGBC4riWY6TzMYiCjcS5JfZIlbhcZe61ej3A48NVBSKCP1XKo0xbKuOHIQuMeeW
|
|
wSaboBwRzJ9JdTXlq5UWfLvmjXDc/HCwk/N7cj021uECgYEA5KkQr3cSKrMIkYoO
|
|
H0Vnkw1kYYGUjtTL00Nfdkv7uGMF122nyt1ND0gpdS0jgNx3LSEam/gY35UWEjGH
|
|
i8DGD04k8pvKDUsl8cuYPcC3oce1lLCGAnw+aHPC5wtA829CLOLtBfxXIhVAI0tp
|
|
ECosD/A63/m1LC19XolOd10/PC8CgYEA3yZChEYZupDGJFZltiy0ZgUarvD2Ss4N
|
|
QiRVR+CmpBrOKZdD8q6uUuqWQN9Rw7kXm8LxAPYwiIDVjxjYALF+j7/9Q1oZyKuv
|
|
eHJdMe4eRUeqeaIKbxnFfKwGZ5rj97jwPrkUCxio75KZhpOcDHMSgBCBtzW0XIZl
|
|
gTeQYOshZQkCgYB5TK6LRnEesabj/gaL1DejrMEJcMIsGvqdceocSSaZo/4fUA5o
|
|
8YjFiJRlkrJ403ttN1h0UOJxCReSQzASlQr8Z4n2IWrILotMf6Kdb7R6YAUVgac1
|
|
fk9k/bPw+OlVujmyshbmy/w1GmzRzFlJt/Vz5w50bnULoH4XPmOfspmvBQKBgBcJ
|
|
rihVzGY0eCBcQxfxuZYmxMB25BaI+1luwtcu3EVo9wvYMA2n9xtcWLLN23UncMaF
|
|
87ezswMEugeR+wrnSDezDISdkrfi8bSvqetzt/BTG8h+8DDUKk1avTaJCSwUDcmL
|
|
9gPHQfmp2uvH5X5riudpzNqLUtmSjnwurlszKzlxAoGAR8STlDJhNph+p3cF8k25
|
|
ydT1kypxnjzVG8CAV5/h3dUmc7j7gyV8NlWZfWacxMZWOBsrdVh0zhMNUPiLJaGd
|
|
I1isOkmiN9JFYMMhHSnhPnTCIjmu6uBLxf8wotHAvzWOJPV7lUZbw21KIN3DS79F
|
|
sGZ2QzGYn4inHG4UHClhZxU=
|
|
-----END PRIVATE KEY-----
|
|
MellonSPCertFile (sp_cert_file):
|
|
pathname: "/etc/httpd/saml2/demo.cert"
|
|
-----BEGIN CERTIFICATE-----
|
|
MIIDDTCCAfWgAwIBAgIJALnqrR7yvGH5MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
|
|
BAMMEm1lbGxvbi5leGFtcGxlLmNvbTAeFw0xNzA4MjgxNTExNDlaFw0yMjA4Mjcx
|
|
NTExNDlaMB0xGzAZBgNVBAMMEm1lbGxvbi5leGFtcGxlLmNvbTCCASIwDQYJKoZI
|
|
hvcNAQEBBQADggEPADCCAQoCggEBAMdRcgsO24zHIU/o5bzWGp+P3P6ALuzFHpTx
|
|
tE8jiAWI2OQ0X7gczKsq1W1/ADlYnW0nghpluDh8ZqmIJxZDm2OO5nsKlnpct6Sr
|
|
rc4auSBnE2bwv4CO9ES/vyJHgzJzjHrJs3UvBCdX6gMXSL1IAQ+d8kJoID7X4MLd
|
|
ErLv7G0rdJWKZRbAAeaQ1To3TAJVI1ifUqCfEFII9PHYOJ9vJGXbVKKiQJ8tKeS0
|
|
T75YHNHOV1LHMyuRJ8WhLv+5Pbfa1t3DY2wmYcYtEaSbIGsQLoFWFDvjo0zVwsO2
|
|
s6i2zts19nfJ9vdbW2mgpU6Ezax7c5Mp2J0BCxoaVW7tAiEGqKcCAwEAAaNQME4w
|
|
HQYDVR0OBBYEFDBbq0pjLeMFPcBt7A++c90lSM5vMB8GA1UdIwQYMBaAFDBbq0pj
|
|
LeMFPcBt7A++c90lSM5vMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
|
|
AFiIxqhW37Td/rD77N648feciigEk/GW4zsqxdx9MspnvSTfr0/lPPOaVhd/UGAw
|
|
g+DwGOmqfisvl44wg07y+4T0NTDzvgkrT0ON5hyEBucFhSjPN+lhwWaH422URwUL
|
|
cKTqkrnAk4Er4bSi1GhsV/2/Xv2ZYyJCcUeiwWQ2fEZXp4ke3IZPN0nYlajKzBTd
|
|
Bv9YlynXKuO1hxBYDWQrrjpp1UZRKjJD2nLUsTi8oFuLhB/RwUMqXZ0nFuNoOkDQ
|
|
XotXjsiL1KtqNW1k/oVtLwNP0trqqh9npWV+R3pDTckxIHQhOvs5VqQZANViH6mp
|
|
YK53b9Bhr0TpIOKetFY68kQ=
|
|
-----END CERTIFICATE-----
|
|
MellonIdPPublicKeyFile (idp_public_key_file):
|
|
file_data: NULL
|
|
MellonIdPCAFile (idp_ca_file):
|
|
file_data: NULL
|
|
MellonIdPMetadataFile (idp_metadata): 1 items
|
|
[ 0] Metadata
|
|
pathname: "/etc/httpd/saml2/demo_keycloak_ipa_idp_metadata.xml"
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!--
|
|
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
~ and other contributors as indicated by the @author tags.
|
|
~
|
|
~ 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.
|
|
-->
|
|
|
|
<EntitiesDescriptor Name="urn:keycloak" xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
|
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
|
|
<EntityDescriptor entityID="https://rhsso.example.com:8443/auth/realms/ipa">
|
|
<IDPSSODescriptor WantAuthnRequestsSigned="true"
|
|
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
|
<KeyDescriptor use="signing">
|
|
<dsig:KeyInfo>
|
|
<dsig:KeyName>R2OGk9W0luNm_NtZbURWOrPlvFzSTDMimCVK5N1Mj5U</dsig:KeyName>
|
|
<dsig:X509Data>
|
|
<dsig:X509Certificate>MIIClTCCAX0CBgFeFdE9pDANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDDANpcGEwHhcNMTcwODI0MTk1NDQ3WhcNMjcwODI0MTk1NjI3WjAOMQwwCgYDVQQDDANpcGEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgIPeag+JJmhtAkIGBwUT/req+jKC6c0Vl1Ngtzbcd07CP9mq1DomBkjuWl59J2urlEfrV4yT8avia0eYE6Dm/TqC74SHt3TVtiUliynAh/z2JvFlLb/EbGePSKrMnuNV8rV75YGcyE12vBRooUPx3hGaygsfaSOg+BijDuCSpbVdWSdVx9VecsWJfxSochOZUj6yvm/qTb8Ptl0x/o7/b/16GgjFRIKSFrdk8pVtMn1wCzpQQoGVHZmp1jrppGcp8KXIK54q7b4pPiTzlW6xhBgrmW2RtWQesCmN8ga1CVeBZKLsaH7argwGH5Ttz31iensqUO0degFu6nwCltgTVAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFx8dl6RDle65q3IHIiGaL5fbJK5HxQiMXpk4N5riWQTP4g6xoTNAG4OFFUd4uRxt2ovdEdkbzhEy2lV4x626QdEfK5V9QKppupsTxTGA/4NMW9QCocAvFSpmYErmJIhfy6zzELoBK4Dpfcc3u1peHx2686msx6ExARF116d+5Xaps1dmPPy3yb2cCKzKbLhieqv+aLLrwz657ERUc4OnqEMEmmHFhHvPI7LRlS4AQ1/s1QlKcM9yqcu8WN3yKM/kuvZtZ0YTCSIl9W1b+I5v8wNoVFB22s7rfxs3DfJFaIImaTmRzaDX0MXgibEckrkigpO+anKe9B9z8CJdtlUHco=</dsig:X509Certificate>
|
|
</dsig:X509Data>
|
|
</dsig:KeyInfo>
|
|
</KeyDescriptor>
|
|
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleLogoutService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</NameIDFormat>
|
|
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
|
|
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleSignOnService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
<SingleSignOnService
|
|
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
|
Location="https://rhsso.example.com:8443/auth/realms/ipa/protocol/saml" />
|
|
</IDPSSODescriptor>
|
|
</EntityDescriptor>
|
|
</EntitiesDescriptor>
|
|
[ 0] Chain File
|
|
file_data: NULL
|
|
MellonIdPIgnore (idp_ignore):
|
|
MellonSPentityId (sp_entity_id): (null)
|
|
MellonOrganizationName (sp_org_name): 0 items
|
|
MellonOrganizationDisplayName (sp_org_display_name): 0 items
|
|
MellonOrganizationURL (sp_org_url): 0 items
|
|
MellonSessionLength (session_length): -1
|
|
MellonNoCookieErrorPage (no_cookie_error_page): (null)
|
|
MellonNoSuccessErrorPage (no_success_error_page): (null)
|
|
MellonDefaultLoginPath (login_path): /
|
|
MellonDiscoveryURL (discovery_url): (null)
|
|
MellonProbeDiscoveryTimeout (probe_discovery_timeout): -1
|
|
MellonProbeDiscoveryIdP (probe_discovery_idp): 0 items
|
|
MellonAuthnContextClassRef (authn_context_class_ref): 0 items
|
|
MellonSubjectConfirmationDataAddressCheck (subject_confirmation_data_address_check): On
|
|
MellonDoNotVerifyLogoutSignature (do_not_verify_logout_signature): 0 items
|
|
MellonPostReplay (post_replay): On
|
|
MellonECPSendIDPList (ecp_send_idplist): On
|
|
enter function am_auth_mellon_user
|
|
searching for session with key 9cf3ebac4e542827e276dc064ce8c4e4 (session) ... found.
|
|
Session Cache Entry
|
|
key: 9cf3ebac4e542827e276dc064ce8c4e4
|
|
name_id: G-e292fc24-74d9-4979-9f81-2c26d85174de
|
|
expires: 2017-08-31T16:15:23Z
|
|
access: 2017-08-30T16:15:23Z
|
|
logged_in: True
|
|
am_check_permissions succeeds
|
|
am_auth_mellon_user am_enable_info, have valid session
|
|
|
|
=== Response ===
|
|
Status: 404 Not Found(404)
|
|
user: G-e292fc24-74d9-4979-9f81-2c26d85174de auth_type=Mellon
|
|
Response Headers:
|
|
Cache-Control: private, max-age=0, must-revalidate
|
|
Content-Length: 209
|
|
Keep-Alive: timeout=5, max=98
|
|
Connection: Keep-Alive
|
|
Content-Type: text/html; charset=iso-8859-1
|
|
Response Error Headers:
|
|
Environment:
|
|
UNIQUE_ID: WabknGfzHRm5EyVgPZnqEgAAAAU
|
|
MELLON_NAME_ID: G-e292fc24-74d9-4979-9f81-2c26d85174de
|
|
MELLON_NAME_ID_0: G-e292fc24-74d9-4979-9f81-2c26d85174de
|
|
MELLON_groups: ipausers
|
|
MELLON_groups_0: ipausers
|
|
MELLON_groups_1: openstack-users
|
|
MELLON_Role: view-profile
|
|
MELLON_Role_0: view-profile
|
|
MELLON_Role_1: uma_authorization
|
|
MELLON_Role_2: manage-account
|
|
MELLON_IDP: https://rhsso.example.com:8443/auth/realms/ipa
|
|
MELLON_IDP_0: https://rhsso.example.com:8443/auth/realms/ipa
|
|
HTTPS: on
|
|
SSL_TLS_SNI: mellon.example.com
|
|
----
|