Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.


Warning
titleEXPERIMENTAL

This feature is experimental. It means that it is not intended for production use. The feature is not finished. It is not stable. The implementation may contain bugs, the configuration may change at any moment without any warning and it may not work at all. Use at your own risk.

Info
titleMidPoint 4.1 and later

Table of Contents

Warning

WORK IN PROGRESS. This functionality is in development. This page can change any time during feature development.

Basic idea of flexible authentication can see is described on Flexible Authentication page. Before we describe configuration of flexible authentication, we have to become acquainted with a few terms.

Basic concepts

Authentication module

Authentication module is basic building unit of flexible authentication. The easiest example of authentication module is classic login form, which we can find on every application. Login form contains field for username or email and password. Login form represent one authentication module, next modules can be authentication by LDAP, HTTP basic authentication, authentication via Identity Provider server, etc. Every Authentication module contains some configuration properties, which define configuration for this kind of authentication module.

Authentication sequence

Authentication sequence is made up of authentication modules, so it contains chain of authentication modules. Each of module have its order in chain and necessity for this sequence. Sequence is define by channel. Channel represents part of Midpoint, for which is valid this authentication sequence, for example GUI, REST service, etc. Also channel contains url suffix for this authentication sequence. So channel define, which authentication sequence will be used for http request.

Authentication channel

Flexible authentication knows following channels:

Request servlet suffixChannelNote

http://midpoint.evolveum.com/xml/ns/public/common/channels-3#userDefault one, represents GUI. No suffix specified.

/ws

/rest

/api

http://midpoint.evolveum.com/xml/ns/public/common/channels-3#rest
/actuatorhttp://midpoint.evolveum.com/xml/ns/public/common/channels-3#actuator
/resetPasswordhttp://midpoint.evolveum.com/xml/ns/public/common/channels-3#resetPassword
/registrationhttp://midpoint.evolveum.com/xml/ns/public/common/channels-3#selfRegistration

Channels for rest and actuator default don't create audit records about session creation or termination. You can turn on it via variable in System Configuration audit->eventRecording->recordSessionlessAccess.

Choosing of Authentication sequence

We can describe flow on two examples.

First example

Midpoint receives HTTP request with URL 'http:localhost:8080/midpoint/actuator/metrics'. Midpoint obtains suffix 'actuator' from URL and it gets channel from table base-on suffix. Obtained channel is configured in used for searching default sequence for channel. Next midpoint initialize found authentication sequence. After successful authentication Midpoint sends request to actuator service.

Second example

Midpoint receives HTTP request with URL 'http:localhost:8080/midpoint/auth/emergency/users'. Midpoint obtains suffix 'auth' from URL, this suffix define using of specific authentication sequence. Midpoint searches authentication sequence base-on next part of URL, in this case 'emergency'. After successful authentication Midpoint sends request to service, which define channel in sequence configuration. Let's say it is GUI for this example, so request is redirect to users page in GUI.

Basic configuration

Flexible authentication is configured in Security Policy, which is used as global security policy in System ConfiguratinConfiguration. Base tag is <authentication>.  Configuration consists of modules and sequences. Module Element module is basic building elementblock of the configuration. Each element has a configuration of a particular authentication element instancemodule instance such as internal password-based authentication, SAML authentication and so on. Each modules module specified in the container must have unique name. Sequence is Element sequence defines a sequence of authentication modules. The modules is are invoked in order as they are specified in the sequence. The purpose of the sequence is to guide user through a complete authentication process.

Module configuration

Now is supported only three modulesOnly following modules are supported nowformLogin, saml2, httpHeader, httpBasic, httpSecQ, securityQuestionsForm, mailNonce, ldap. Each from contains element contains common attributes:

NameDescriptionRequiredTypeDefault
name

Unique name of the authentication module. This name is fact a short identifier. It is supposed to give some idea about nature of the module to system administrator. But it is not supposed to be used as a user-friendly label for the module. The name is also used in the url, so it should not contain special characters.

trueString
descriptionFree form description of the module (administrator comment).falseString

formLogin module


focusTypeType of logged object that this authentication module applies to. E.g UserType, RoleType, OrgType, ...false
UserType

Module formLogin

FormLogin module is used for interactive log-in of a user by using HTML forms. 

Code Block
languagexml
titleExample of formLogin module
linenumberstrue
<loginForm>
	<name>internalLoginForm</name>
    <description>Internal username/password authentication, default user password, login form</description>
</loginForm>

Module httpBasic

Definition of HTTP BASIC authentication module (RFC 7617).

Code Block
languagexml
titleExample of httpBasic module
linenumberstrue
<httpBasic>
	<name>internalHttpBasic</name>
    <description>Http basic username/password authentication, default user password</description>
</httpBasic>

Module httpSecQ

Definition of HTTP SecQ module. The module is used for quasi-interactive log-in of a user by answering a set of security questions. The HTTP SecQ mechanism is similar to HTTP BASIC mechanism, but it is using security questions instead of password.

Code Block
languagexml
titleExample of httpBasic module
linenumberstrue
<httpSecQ>
	<name>httpSecurityQuestions</name>
</httpSecQ>

Module securityQuestionsForm

Definition of "security questions form" module. The module is used for interactive log-in of a user by answering a set of security questions.

Code Block
languagexml
titleExample of securityQuestionsFrom module
linenumberstrue
<securityQuestionsForm>
	<name>securityQuestions</name>
</securityQuestionsForm>

Module mailNonce

Mail nonce authentication module. Module that sends randomly generated nonce in URL in mail message. This module contains next attribute:

NameDescriptionRequiredType
credentialNameName of credential definition that should be used when validating password. This must point to a valid credential definition in the "credential" section of a security policy. If not specified then default password definition is used.falseString


Code Block
languagexml
titleExample of mailNonce module
linenumberstrue
<mailNonce>
	<name>securityQuestions</name>
	<credentialName>mailNonceCredential</credentialName>
</mailNonce>

Module ldap

LDAP authentication module supports authentication via LDAP server. This module contains next attributes:

NameDescriptionRequiredType
hostHost of the LDAP server.trueString
userDnThe user distinguished name.trueString
userPasswordThe password (credentials) to use for getting authenticated contexts.trueString
dnPatternThe pattern which will be used to supply a DN for the user.falseString
searchSearch configuration which uses an Ldap filter to locate the user.falseAuthenticationModuleLdapSearchType

AuthenticationModuleLdapSearchType

NameDescriptionRequiredType
patternThe filter expression used in the user search. This is an LDAP search filter (as defined in 'RFC 2254') with optional arguments. Example (uid={0})trueString
namingAttrSpecifying explicit LDAP attribute that is retrieved from user's LDAP account and contains value that matches midPoint's username.falseString
subtreeIf true then searches the entire subtree as identified by context, if false (the default) then only searches the level identified by the context.falseBoolean


Code Block
languagexml
titleExample of ldap module
linenumberstrue
<ldap>
	<name>ldapAuth</name>
	<host>ldap://localhost:389/dc=example,dc=com</host>
	<userDn>cn=admin,dc=example,dc=com</userDn>
	<userPassword>
        <t:clearValue>secret</t:clearValue>
    </userPassword>
    <dnPattern>uid={0},ou=people</dnPattern>
    <search>
        <pattern>(uid={0})</pattern>
        <namingAttr>uid</namingAttr>
        <subtree>true</subtree>
    </search>
</ldap>

Module httpHeader

Pseudo-authentication for pre-authenticated users. Based on HTTP header values. This module contains specific attributes:

NameDescriptionRequiredType
usernameHeaderName of HTTP header that contains username.trueString
logoutUrlUrl for redirect after logout. Default is '/'.falseString

...

Code Block
languagexml
titleExample of httpHeader module
linenumberstrue
<httpHeader><httpHeader>AuthenticationModuleSaml2ProviderMetadataType
	<name>httpHeader</name>
    	<logoutUrl>http://localhost:8081/Identity_provider/Logout</logoutUrl>
        <usernameHeader>uid</usernameHeader>
</httpHeader>

Module saml2

SAML2 authentication module support supports authentication via Identity provider with SAML2. SAML2 module have little has a little bit complicated configuration. This module contains specific attributes:

NameDescriptionRequiredType
serviceProviderBasic configuration of SP.trueAuthenticationModuleSaml2ServiceProviderType
networkNetwork configuration of REST requests.falseAuthenticationModuleSaml2NetworkType

...

AuthenticationModuleSaml2NetworkType have only two attributes:

NameRequiredType
readTimeoutfalseint
connectTimeoutfalseint

AuthenticationModuleSaml2ServiceProviderType

...

NameDescriptionRequiredTypeDefault
entityIdUnique identifier of the service provider.trueString
aliasUnique alias used to identify the selected local service provider based on used URL.falseStringBase-on sequence and name of module
aliasForPathAlias used for AssertionConsumerServiceURL.falseString
defaultSigningAlgorithmDefault signing algorithm. Possible values are RSA_SHA1, RSA_SHA256, RSA_SHA512 and RSA_RIPEMD160.falseenumRSA_SHA256
defaultDigestDefault digest method. possible values are  SHA1, SHA256, SHA512 and RIPEMD160.falseenumSHA256
signMetadataWhen true generated metadata will be signed using XML Signature using certificate with alias of signing key.falsebooleanfalse
signRequestsFlag indicating whether this service signs authentication requests.falsebooleanfalse
wantAssertionsSignedFlag indicating whether this service requires signed assertions.falsebooleanfalse
singleLogoutEnabledFlag indicating whether this service enable single logout.falsebooleantrue
nameIdName identifiers to be included in the metadata. Supported values are: EMAIL, TRANSIENT, PERSISTENT, UNSPECIFIED and X509_SUBJECT. Order of NameIDs in the property determines order of NameIDs in the generated metadata.falseenum
keysKey used by service provider.truefalseAuthenticationModuleSaml2KeyType
providerPossible identity providers for this service provider.trueAuthenticationModuleSaml2ProviderType
metadataService provider can use prepared metadata.falseAuthenticationModuleSaml2MetadataTypeAuthenticationModuleSaml2ProviderMetadataType

AuthenticationModuleSaml2KeyType

AuthenticationModuleSaml2KeyType contains only two attributes 'active'  and 'standBy', both are type AuthenticationModuleSaml2SimpleKeyType, which contains contains following configuration attributes:

NameDescriptionRequiredType
activeSimpleKeyBase key used for signing and encryption. You can use only one from active keys, or can be both null.trueModuleSaml2SimpleKeyType
activeKeyStoreKeyBase key used for signing and encryption. You can use only one from active keys, or can be both null.trueModuleSaml2KeyStoreKeyType
standBySimpleKeyOther keys. trueModuleSaml2SimpleKeyType
standByKeyStoreKeyOther keys.trueModuleSaml2KeyStoreKeyType

ModuleSaml2SimpleKeyType

ModuleSaml2SimpleKeyType contains following attributes:

NameDescriptionRequiredType
nameName of key.trueString
privateKeyPrivate key.trueProtectedStringType
passphrasePassword.trueProtectedStringType
certificateCertificate of key.trueProtectedStringType
typeType of key. Possible values are SIGNING, UNSPECIFIED and ENCRYPTION.falseenum

AuthenticationModuleSaml2ProviderType

...


Code Block
languagexml
titleExample of ModuleSaml2SimpleKeyType
linenumberstrue
<activeSimpleKey>
	<name>sp-signing-key</name>
    <privateKey>
    	<t:clearValue>"primary key"</t:clearValue>
    </privateKey>
    <passphrase>
        <t:clearValue>"password"</t:clearValue>
    </passphrase>
    <certificate>
        <t:clearValue>"certificate"</t:clearValue>
    </certificate>
</activeSimpleKey>

ModuleSaml2KeyStoreKeyType

ModuleSaml2KeyStoreKeyType contains following attributes:

NameDescriptionRequiredType
keyStorePathPath to KeyStore.trueString
keyStorePasswordPassword of KeyStore.trueProtectedStringType
keyAliasAlias of private key in KeyStore.trueProtectedStringType
keyPasswordPassword of private key with alias 'keyAlias' in KeyStore.trueProtectedStringType
typeType of key. Possible values are SIGNING, UNSPECIFIED and ENCRYPTION.falseenum


Code Block
languagexml
titleExample of ModuleSaml2KeyStoreKeyType
linenumberstrue
<activeKeyStoreKey>
	<keyStorePath>/home/lskublik/keyStore</keyStorePath>
    <keyStorePassword>
		<t:clearValue>"password of keyStore"</t:clearValue>
    </keyStorePassword>
    <keyAlias>sp-signing-key-1</keyAlias>
    <keyPassword>
		<t:clearValue>"password of private key"</t:clearValue>
    </keyPassword>
</activeKeyStoreKey>

AuthenticationModuleSaml2ProviderType

AuthenticationModuleSaml2ProviderType represents one Identity Providers. AuthenticationModuleSaml2ProviderType contains following attributes:

NameDescriptionRequiredTypeDefrault
entityIdUnique identifier of the service provider.trueString
aliasUnique alias used to identify the selected local service provider based on used URL.trueString
metadataMetadata of Identity provider.trueAuthenticationModuleSaml2MetadataType
skipSslValidationFlag for skipping of ssl validation.falsebooleanfalse
metadataTrustCheckFlag indicating disabled signature verification.flasebooleanfalse
linkTextUser friendly name of provider.falseString
authenticationRequestBindingSAML2 binding used for authentication request.trueString
verificationKeys
falseProtectedStringType
nameOfUsernameAttributeName of attribute in response, which value define name of user in Midpoint. For example 'uid'.trueString

AuthenticationModuleSaml2MetadataType

...


AuthenticationModuleSaml2ProviderMetadataType

AuthenticationModuleSaml2ProviderMetadataType represents metadata of provider. You can choise choose from one definition for metadata: metadataUrlxml and pathToFile.

NameDescription
metadataUrlURL, which show metadata.
xmlXml of metadata encrypted by base64.
pathToFilePath to xml file, which contains metadata.


Code Block
languagexml
titleExample of saml2 module
linenumberstrue
<saml2>
	<name>mySamlSso</name>
    <description>My internal enterprise SAML-based SSO system.</description>
    <network>
    	<readTimeout>10000</readTimeout>
        <connectTimeout>5000</connectTimeout>
    </network>
    <serviceProvider>
    	<entityId>sp_midpoint</entityId>
        <signMetadata>true</signMetadata>
        <signRequests>true</signRequests>
        <wantAssertionsSigned>true</wantAssertionsSigned>
        <singleLogoutEnabled>true</singleLogoutEnabled>
        <nameId>TRANSIENT</nameId>
        <keys>
        	<active>    .
        	<name>sp-signing-key</name>			.
			.
                <privateKey>
                    <t:clearValue>"primary key"</t:clearValue>
                </privateKey>
                <passphrase>
                    <t:clearValue>"password"</t:clearValue>
                </passphrase>
                <certificate>
                    <t:clearValue>"certificate"</t:clearValue>
                </certificate>
            </active>
        </keys>
        <provider>
        	<entityId>https://idptestbed/idp/shibboleth</entityId>
            <alias>simplesamlphp</alias>
            <metadata>
		<xml>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KICAgICAgICAgICAgICA8IS0tCiAgICAgICAgICAgICAgICAgICBUaGlzIGlzIGV4YW1wbGUgbWV0YWRhdGEgb25seS4gRG8gKk5PVCogc3VwcGx5IGl0IGFzIGlzIHdpdGhvdXQgcmV2aWV3LAogICAgICAgICAgICAgICAgICAgYW5kIGRvICpOT1QqIHByb3ZpZGUgaXQgaW4gcmVhbCB0aW1lIHRvIHlvdXIgcGFydG5lcnMuCgogICAgICAgICAgICAgICAgICAgVGhpcyBtZXRhZGF0YSBpcyBub3QgZHluYW1pYyAtIGl0IHdpbGwgbm90IGNoYW5nZSBhcyB5b3VyIGNvbmZpZ3VyYXRpb24gY2hhbmdlcy4KICAgICAgICAgICAgICAtLT4KICAgICAgICAgICAgICA8RW50aXR5RGVzY3JpcHRvciAgeG1sbnM9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDptZXRhZGF0YSIgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiIHhtbG5zOnNoaWJtZD0idXJuOm1hY2U6c2hpYmJvbGV0aDptZXRhZGF0YToxLjAiIHhtbG5zOnhtbD0iaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIiB4bWxuczptZHVpPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDptZXRhZGF0YTp1aSIgZW50aXR5SUQ9Imh0dHBzOi8vaWRwdGVzdGJlZC9pZHAvc2hpYmJvbGV0aCI+CgogICAgICAgICAgICAgICAgICA8SURQU1NPRGVzY3JpcHRvciBwcm90b2NvbFN1cHBvcnRFbnVtZXJhdGlvbj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIHVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpwcm90b2NvbCB1cm46bWFjZTpzaGliYm9sZXRoOjEuMCI+CgogICAgICAgICAgICAgICAgICAgICAgPEV4dGVuc2lvbnM+CiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNoaWJtZDpTY29wZSByZWdleHA9ImZhbHNlIj5leGFtcGxlLm9yZzwvc2hpYm1kOlNjb3BlPgogICAgICAgICAgICAgIDwhLS0KICAgICAgICAgICAgICAgICAgRmlsbCBpbiB0aGUgZGV0YWlscyBmb3IgeW91ciBJZFAgaGVyZQoKICAgICAgICAgICAgICAgICAgICAgICAgICA8bWR1aTpVSUluZm8+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtZHVpOkRpc3BsYXlOYW1lIHhtbDpsYW5nPSJlbiI+QSBOYW1lIGZvciB0aGUgSWRQIGF0IGlkcHRlc3RiZWQ8L21kdWk6RGlzcGxheU5hbWU+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtZHVpOkRlc2NyaXB0aW9uIHhtbDpsYW5nPSJlbiI+RW50ZXIgYSBkZXNjcmlwdGlvbiBvZiB5b3VyIElkUCBhdCBpZHB0ZXN0YmVkPC9tZHVpOkRlc2NyaXB0aW9uPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWR1aTpMb2dvIGhlaWdodD0iODAiIHdpZHRoPSI4MCI+aHR0cHM6Ly9pZHB0ZXN0YmVkL1BhdGgvVG8vTG9nby5wbmc8L21kdWk6TG9nbz4KICAgICAgICAgICAgICAgICAgICAgICAgICA8L21kdWk6VUlJbmZvPgogICAgICAgICAgICAgIC0tPgogICAgICAgICAgICAgICAgICAgICAgPC9FeHRlbnNpb25zPgoKICAgICAgICAgICAgICAgICAgICAgIDxLZXlEZXNjcmlwdG9yIHVzZT0ic2lnbmluZyI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRzOktleUluZm8+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHM6WDUwOURhdGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRzOlg1MDlDZXJ0aWZpY2F0ZT4KICAgICAgICAgICAgICBNSUlERXpDQ0FmdWdBd0lCQWdJVVM5U3VUWHdzRlZWRytMak9FQWJMcXFUL2VsMHdEUVlKS29aSWh2Y05BUUVMCiAgICAgICAgICAgICAgQlFBd0ZURVRNQkVHQTFVRUF3d0thV1J3ZEdWemRHSmxaREFlRncweE5URXlNVEV3TWpJd01qWmFGdzB6TlRFeQogICAgICAgICAgICAgIE1URXdNakl3TWpaYU1CVXhFekFSQmdOVkJBTU1DbWxrY0hSbGMzUmlaV1F3Z2dFaU1BMEdDU3FHU0liM0RRRUIKICAgICAgICAgICAgICBBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ01Bb0RIeDh4Q0lmdi82UUtxdDltY0hZbUVKOHkyZEtwclVicGRjT2pICiAgICAgICAgICAgICAgWXZOUElsL2xIUHNVeXJiK05jK3EyQ0RlaVdqVmsxbVdZcTBVcEl3cEJNdXcxSDYrb09xcjRWUVJpNjVwaW4wTQogICAgICAgICAgICAgIFNmRTBNV0lhRm81RlB2cHZvcHRrSEQ0Z3ZSRWJtNHN3eVhHTWN6Y01SZnFnYWxGWGhVRDJ3ejhXM1hBTTVDcTIKICAgICAgICAgICAgICAwM1hlSmJqNlR3anZLYXRHNVhQZGVVZTJGQkd1T08ycTU0TDFoY0lHbkxNQ1FyZzdEMzFsUjEzUEpiam5KME5vCiAgICAgICAgICAgICAgNUMzazhUUHVueTZ2SnNCQzAzR05MTktmbXJLVlRkenIzVktwMXVheTFHM0RMOTMxNGZnbWJsOEhBNWlSUW15KwogICAgICAgICAgICAgIFhJblVVNi84TlhaU0Y1OXAzSVRBT3ZaUWVac2JKamc1Z0dEaXA1T1pvOVlsQWdNQkFBR2pXekJaTUIwR0ExVWQKICAgICAgICAgICAgICBEZ1FXQkJSUGxNNFZrS1owVTRlYzlHckloRlFsMGhOYkxEQTRCZ05WSFJFRU1UQXZnZ3BwWkhCMFpYTjBZbVZrCiAgICAgICAgICAgICAgaGlGb2RIUndjem92TDJsa2NIUmxjM1JpWldRdmFXUndMM05vYVdKaWIyeGxkR2d3RFFZSktvWklodmNOQVFFTAogICAgICAgICAgICAgIEJRQURnZ0VCQUlaMGExb3YzbXkzbGpKRzU4OEkvUEh4K1R4QVdPTldtcEtiTzljL3FJM0RyeGs0b1JJZmZpYWMKICAgICAgICAgICAgICBBTnhkdnRhYmdJenJsazVnTU1pc0Q3b3lxSEppV2dLdjVCZ2N0ZDh3M0lTM2xMbDd3SFg2NW1US1FSWG5pRzk4CiAgICAgICAgICAgICAgTklqa3ZmcmhlMmVlSnhlY09xbkRJOEdPaElHQ0lxWlVuOFNoZE0veUhqaFEyTWgwSGozVTBMbEt2bm1mR1NRbAogICAgICAgICAgICAgIGowdmlHd2JGQ2FOYUlQM3pjNVVtQ3JkRTVoOHNXTDNGdTdJTEtNOVJ5RmEySUxIckpTY1Y5dDYyM0ljSGZmSFAKICAgICAgICAgICAgICBJZWFZL1d0dWFwc3JxUkZ4dVFMOVFGV04wRnNSSWRMbWpUcSswMCtCL1hubktSS0ZCdVdmamhITEYvdXU4ZitFCiAgICAgICAgICAgICAgdDZMZjIzS2I4eUQ2WlI3ZGloTVpBR0huWVEvaGxoTT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2RzOlg1MDlDZXJ0aWZpY2F0ZT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZHM6WDUwOURhdGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kczpLZXlJbmZvPgoKICAgICAgICAgICAgICAgICAgICAgIDwvS2V5RGVzY3JpcHRvcj4KICAgICAgICAgICAgICAgICAgICAgIDxLZXlEZXNjcmlwdG9yIHVzZT0ic2lnbmluZyI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRzOktleUluZm8+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHM6WDUwOURhdGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRzOlg1MDlDZXJ0aWZpY2F0ZT4KICAgICAgICAgICAgICBNSUlERkRDQ0FmeWdBd0lCQWdJVkFOM3Z2K2I3S041U2U5bTFSWnNDbGxwL0IvaGRNQTBHQ1NxR1NJYjNEUUVCCiAgICAgICAgICAgICAgQ3dVQU1CVXhFekFSQmdOVkJBTU1DbWxrY0hSbGMzUmlaV1F3SGhjTk1UVXhNakV4TURJeU1ERTBXaGNOTXpVeAogICAgICAgICAgICAgIE1qRXhNREl5TURFMFdqQVZNUk13RVFZRFZRUUREQXBwWkhCMFpYTjBZbVZrTUlJQklqQU5CZ2txaGtpRzl3MEIKICAgICAgICAgICAgICBBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFoOTFjYWVZMFE4NXVoYVV5cUZ3UDJiTWp3TUZ4TXpSbEFvcUJIZDdnCiAgICAgICAgICAgICAgdTZlbzRkdWFlTHoxQmFvUjJYVEJwTk52RlI1b0hIK1RrS2FoVkRHZUg1K2tjbklweEk4SlBkc1ptbDFzcnZmMgogICAgICAgICAgICAgIFo2ZHpKc3VsSlpVZHBxbm5neWNUa0d0WmdFb0Mxdm1ZVmt5MkJTQUlJaWZtZGg2czBlcGJIbk1HTHNIek1LZkoKICAgICAgICAgICAgICBDYi9RNmRZelJXVENQdHpFMlZNdVFxcVdnZXlNcjd1MTR4L1ZxcjlSUEVGc2dZOEdJdTVqekI2QXlVSXdyTGcrCiAgICAgICAgICAgICAgTU5rdjZhSWRjSHd4WVRHTDdpamZ5NnJTV3JnQmZsUW9ZUllORW5zZUswWkhnSmFoejRvdkNhZzZ3WkFvUHBCcwogICAgICAgICAgICAgIHVZbFk3bEVyODlVY2I2Tkh4M3VxR01zWGxERmRFNFF3ZkRMTGhDWUhQdkowdXdJREFRQUJvMXN3V1RBZEJnTlYKICAgICAgICAgICAgICBIUTRFRmdRVUFrT2dFRDNpWWRtdlFFT01tNnUvSm1EL1VUUXdPQVlEVlIwUkJERXdMNElLYVdSd2RHVnpkR0psCiAgICAgICAgICAgICAgWklZaGFIUjBjSE02THk5cFpIQjBaWE4wWW1Wa0wybGtjQzl6YUdsaVltOXNaWFJvTUEwR0NTcUdTSWIzRFFFQgogICAgICAgICAgICAgIEN3VUFBNElCQVFCSWRkNFlXbG52SmpxbDgrektLZ21XZ0lZN1U4REE4ZTZRY2JBZjhmOGNkRTMzUlNuakk2M1gKICAgICAgICAgICAgICBzdi95OUdmbWJBVkFENlJJQVhQRkZlUllKMDhHT3hHSTlheGZOYUtkbHNrbEo5Yms0ZHVjSHFnQ1NXWVZlcjNzCiAgICAgICAgICAgICAgUlFCanh5T2ZTVHZrOVlDSnZkSlZRUkpMY0N2eHdLYWtGQ3NPU25WM3Q5T3ZOODZBaytmS1BWQjVqMmZNLzBmWgogICAgICAgICAgICAgIEtxam4zaXFnZE5QVExYUHN1SkxKTzVsSVRSaUJhNG9ubVZlbEFpQ3N0STlQUWlhRWNrK29BSG5NVG5DOUpFL0IKICAgICAgICAgICAgICBESHYzZTRyd3EzTHpubHFQdzBHU2Q3eHFOVGRNRHdOT1dqa3VPcjNzR3BXUzhtcy9aSEhYVjFWZDIydVBlNzBpCiAgICAgICAgICAgICAgczAweHJ2MTR6TGlmY2M4b2o1RFl6T2hZUmlmUlhnSFgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2RzOlg1MDlDZXJ0aWZpY2F0ZT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZHM6WDUwOURhdGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kczpLZXlJbmZvPgoKICAgICAgICAgICAgICAgICAgICAgIDwvS2V5RGVzY3JpcHRvcj4KICAgICAgICAgICAgICAgICAgICAgIDxLZXlEZXNjcmlwdG9yIHVzZT0iZW5jcnlwdGlvbiI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRzOktleUluZm8+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHM6WDUwOURhdGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRzOlg1MDlDZXJ0aWZpY2F0ZT4KICAgICAgICAgICAgICBNSUlERXpDQ0FmdWdBd0lCQWdJVUc2Tm4xcmxFUlMxdnNpODh0Y2R6U1lYMG9xQXdEUVlKS29aSWh2Y05BUUVMCiAgICAgICAgICAgICAgQlFBd0ZURVRNQkVHQTFVRUF3d0thV1J3ZEdWemRHSmxaREFlRncweE5URXlNVEV3TWpJd01UUmFGdzB6TlRFeQogICAgICAgICAgICAgIE1URXdNakl3TVRSYU1CVXhFekFSQmdOVkJBTU1DbWxrY0hSbGMzUmlaV1F3Z2dFaU1BMEdDU3FHU0liM0RRRUIKICAgICAgICAgICAgICBBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ0JYdjBvM2ZtVDhpbHV5TGpKNGxCQVZDVytaUlZ5RVhQWVF1Umk3dmZECiAgICAgICAgICAgICAgY080YTZkMWt4aUpMc2FLMFc4OFZOeGpGUVJyOFBnRGtXcjI4dndvSDFyZ2s0cExzc3pMRDQ4REJ6RDk0MnBlSgogICAgICAgICAgICAgIGwvUzZGbnNJSmptYUhjQmg0cGJOaFU0eW93dTYzaUtrdnR0cmNaQUVicEVybzZaOEN6aVdFeDhzeXdvYVlFUUcKICAgICAgICAgICAgICBpZlBrcjlPUlY2Q24zdHhxKzlnTUJlUEc0MUdydFpyVUdJdSt4cm5kTDBTaGg0UHEwZXEvOU1Bc1ZsSUlYRWE4CiAgICAgICAgICAgICAgOVdmSDhKMmtGY1RPZm9XdEljNzBiN1RMWlFzeDRZbk5jbnJHTFNVRWNzdEZ5UExYK1h0djVTTlpGODlPT0l4WAogICAgICAgICAgICAgIFZOak52Z0U1RGJKYjloTU00VUFGcUkrMWJvOVFxdHh3VGhqYy9zT3ZJeHpOQWdNQkFBR2pXekJaTUIwR0ExVWQKICAgICAgICAgICAgICBEZ1FXQkJTdFR5b2dSUHVBVkc2cTd5UHlhdjF1dkUrN3BUQTRCZ05WSFJFRU1UQXZnZ3BwWkhCMFpYTjBZbVZrCiAgICAgICAgICAgICAgaGlGb2RIUndjem92TDJsa2NIUmxjM1JpWldRdmFXUndMM05vYVdKaWIyeGxkR2d3RFFZSktvWklodmNOQVFFTAogICAgICAgICAgICAgIEJRQURnZ0VCQUZNZm9PditvSVNHanZhbXE3K1k0RzdlcDV2eGxBUGVLM1JBVFlQWXZBbXlIOTQ2cVpYaDk4bmkKICAgICAgICAgICAgICBRWHl1cVpXNVA1ZUV0ODZ0b1k0NUl3RFU1cjA5U0t3SHVnaEVlOTlpaUVreGgwbWIycW84NHFYOS9xY2cra3lOCiAgICAgICAgICAgICAgamVMZC9PU3lvbHBVQ0VGTndPRmNvZzdwajdFZXIrNkFIYndUbjFNamI1VEJzS3d0RE1Kc2F4UHZkajB1N001cgogICAgICAgICAgICAgIHhML3dIa0ZobjFyQ28yUWlvanpqU2xWM3lMVGg0OWlUeWhFM2NHK1J4YU5LREN4aHAwalNTTFgxQlcvWm9QQTgKICAgICAgICAgICAgICArUE1KRUErUTBRYnlSRDhhSk9ITjVPOGpHeENhL1p6Y09uWVZMNkFzRVhvRGlZM3ZBVVloMUZVb25PV3cwbTlICiAgICAgICAgICAgICAgcCt0R1ViR1MybDg3M0o1UHJzYnBlS0VWUi9JSW9Lbz0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2RzOlg1MDlDZXJ0aWZpY2F0ZT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZHM6WDUwOURhdGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kczpLZXlJbmZvPgoKICAgICAgICAgICAgICAgICAgICAgIDwvS2V5RGVzY3JpcHRvcj4KCiAgICAgICAgICAgICAgICAgICAgICA8QXJ0aWZhY3RSZXNvbHV0aW9uU2VydmljZSBCaW5kaW5nPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjA6YmluZGluZ3M6U09BUC1iaW5kaW5nIiBMb2NhdGlvbj0iaHR0cHM6Ly9pZHB0ZXN0YmVkOjg0NDMvaWRwL3Byb2ZpbGUvU0FNTDEvU09BUC9BcnRpZmFjdFJlc29sdXRpb24iIGluZGV4PSIxIi8+CiAgICAgICAgICAgICAgICAgICAgICA8QXJ0aWZhY3RSZXNvbHV0aW9uU2VydmljZSBCaW5kaW5nPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YmluZGluZ3M6U09BUCIgTG9jYXRpb249Imh0dHBzOi8vaWRwdGVzdGJlZDo4NDQzL2lkcC9wcm9maWxlL1NBTUwyL1NPQVAvQXJ0aWZhY3RSZXNvbHV0aW9uIiBpbmRleD0iMiIvPgoKCiAgICAgICAgICAgICAgICAgICAgICA8U2luZ2xlTG9nb3V0U2VydmljZSBCaW5kaW5nPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YmluZGluZ3M6SFRUUC1SZWRpcmVjdCIgTG9jYXRpb249Imh0dHBzOi8vaWRwdGVzdGJlZC9pZHAvcHJvZmlsZS9TQU1MMi9SZWRpcmVjdC9TTE8iLz4KICAgICAgICAgICAgICAgICAgICAgIDxTaW5nbGVMb2dvdXRTZXJ2aWNlIEJpbmRpbmc9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpiaW5kaW5nczpIVFRQLVBPU1QiIExvY2F0aW9uPSJodHRwczovL2lkcHRlc3RiZWQvaWRwL3Byb2ZpbGUvU0FNTDIvUE9TVC9TTE8iLz4KICAgICAgICAgICAgICAgICAgICAgIDxTaW5nbGVMb2dvdXRTZXJ2aWNlIEJpbmRpbmc9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpiaW5kaW5nczpIVFRQLVBPU1QtU2ltcGxlU2lnbiIgTG9jYXRpb249Imh0dHBzOi8vaWRwdGVzdGJlZC9pZHAvcHJvZmlsZS9TQU1MMi9QT1NULVNpbXBsZVNpZ24vU0xPIi8+CiAgICAgICAgICAgICAgICAgICAgICA8U2luZ2xlTG9nb3V0U2VydmljZSBCaW5kaW5nPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YmluZGluZ3M6U09BUCIgTG9jYXRpb249Imh0dHBzOi8vaWRwdGVzdGJlZDo4NDQzL2lkcC9wcm9maWxlL1NBTUwyL1NPQVAvU0xPIi8+CgoKCiAgICAgICAgICAgICAgICAgICAgICA8TmFtZUlERm9ybWF0PnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpuYW1laWQtZm9ybWF0OnRyYW5zaWVudDwvTmFtZUlERm9ybWF0PgogICAgICAgICAgICAgICAgICAgICAgPE5hbWVJREZvcm1hdD51cm46bWFjZTpzaGliYm9sZXRoOjEuMDpuYW1lSWRlbnRpZmllcjwvTmFtZUlERm9ybWF0PgoKICAgICAgICAgICAgICAgICAgICAgIDxTaW5nbGVTaWduT25TZXJ2aWNlIEJpbmRpbmc9InVybjptYWNlOnNoaWJib2xldGg6MS4wOnByb2ZpbGVzOkF1dGhuUmVxdWVzdCIgTG9jYXRpb249Imh0dHBzOi8vaWRwdGVzdGJlZC9pZHAvcHJvZmlsZS9TaGliYm9sZXRoL1NTTyIvPgogICAgICAgICAgICAgICAgICAgICAgPFNpbmdsZVNpZ25PblNlcnZpY2UgQmluZGluZz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmJpbmRpbmdzOkhUVFAtUE9TVCIgTG9jYXRpb249Imh0dHBzOi8vaWRwdGVzdGJlZC9pZHAvcHJvZmlsZS9TQU1MMi9QT1NUL1NTTyIvPgogICAgICAgICAgICAgICAgICAgICAgPFNpbmdsZVNpZ25PblNlcnZpY2UgQmluZGluZz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmJpbmRpbmdzOkhUVFAtUE9TVC1TaW1wbGVTaWduIiBMb2NhdGlvbj0iaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9wcm9maWxlL1NBTUwyL1BPU1QtU2ltcGxlU2lnbi9TU08iLz4KICAgICAgICAgICAgICAgICAgICAgIDxTaW5nbGVTaWduT25TZXJ2aWNlIEJpbmRpbmc9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpiaW5kaW5nczpIVFRQLVJlZGlyZWN0IiBMb2NhdGlvbj0iaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9wcm9maWxlL1NBTUwyL1JlZGlyZWN0L1NTTyIvPgoKICAgICAgICAgICAgICAgICAgPC9JRFBTU09EZXNjcmlwdG9yPgoKCiAgICAgICAgICAgICAgICAgIDxBdHRyaWJ1dGVBdXRob3JpdHlEZXNjcmlwdG9yIHByb3RvY29sU3VwcG9ydEVudW1lcmF0aW9uPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6cHJvdG9jb2wiPgoKICAgICAgICAgICAgICAgICAgICAgIDxFeHRlbnNpb25zPgogICAgICAgICAgICAgICAgICAgICAgICAgIDxzaGlibWQ6U2NvcGUgcmVnZXhwPSJmYWxzZSI+ZXhhbXBsZS5vcmc8L3NoaWJtZDpTY29wZT4KICAgICAgICAgICAgICAgICAgICAgIDwvRXh0ZW5zaW9ucz4KCiAgICAgICAgICAgICAgICAgICAgICA8S2V5RGVzY3JpcHRvciB1c2U9InNpZ25pbmciPgogICAgICAgICAgICAgICAgICAgICAgICAgIDxkczpLZXlJbmZvPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRzOlg1MDlEYXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkczpYNTA5Q2VydGlmaWNhdGU+CiAgICAgICAgICAgICAgTUlJREV6Q0NBZnVnQXdJQkFnSVVTOVN1VFh3c0ZWVkcrTGpPRUFiTHFxVC9lbDB3RFFZSktvWklodmNOQVFFTAogICAgICAgICAgICAgIEJRQXdGVEVUTUJFR0ExVUVBd3dLYVdSd2RHVnpkR0psWkRBZUZ3MHhOVEV5TVRFd01qSXdNalphRncwek5URXkKICAgICAgICAgICAgICBNVEV3TWpJd01qWmFNQlV4RXpBUkJnTlZCQU1NQ21sa2NIUmxjM1JpWldRd2dnRWlNQTBHQ1NxR1NJYjNEUUVCCiAgICAgICAgICAgICAgQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUNNQW9ESHg4eENJZnYvNlFLcXQ5bWNIWW1FSjh5MmRLcHJVYnBkY09qSAogICAgICAgICAgICAgIFl2TlBJbC9sSFBzVXlyYitOYytxMkNEZWlXalZrMW1XWXEwVXBJd3BCTXV3MUg2K29PcXI0VlFSaTY1cGluME0KICAgICAgICAgICAgICBTZkUwTVdJYUZvNUZQdnB2b3B0a0hENGd2UkVibTRzd3lYR01jemNNUmZxZ2FsRlhoVUQyd3o4VzNYQU01Q3EyCiAgICAgICAgICAgICAgMDNYZUpiajZUd2p2S2F0RzVYUGRlVWUyRkJHdU9PMnE1NEwxaGNJR25MTUNRcmc3RDMxbFIxM1BKYmpuSjBObwogICAgICAgICAgICAgIDVDM2s4VFB1bnk2dkpzQkMwM0dOTE5LZm1yS1ZUZHpyM1ZLcDF1YXkxRzNETDkzMTRmZ21ibDhIQTVpUlFteSsKICAgICAgICAgICAgICBYSW5VVTYvOE5YWlNGNTlwM0lUQU92WlFlWnNiSmpnNWdHRGlwNU9abzlZbEFnTUJBQUdqV3pCWk1CMEdBMVVkCiAgICAgICAgICAgICAgRGdRV0JCUlBsTTRWa0taMFU0ZWM5R3JJaEZRbDBoTmJMREE0QmdOVkhSRUVNVEF2Z2dwcFpIQjBaWE4wWW1WawogICAgICAgICAgICAgIGhpRm9kSFJ3Y3pvdkwybGtjSFJsYzNSaVpXUXZhV1J3TDNOb2FXSmliMnhsZEdnd0RRWUpLb1pJaHZjTkFRRUwKICAgICAgICAgICAgICBCUUFEZ2dFQkFJWjBhMW92M215M2xqSkc1ODhJL1BIeCtUeEFXT05XbXBLYk85Yy9xSTNEcnhrNG9SSWZmaWFjCiAgICAgICAgICAgICAgQU54ZHZ0YWJnSXpybGs1Z01NaXNEN295cUhKaVdnS3Y1QmdjdGQ4dzNJUzNsTGw3d0hYNjVtVEtRUlhuaUc5OAogICAgICAgICAgICAgIE5Jamt2ZnJoZTJlZUp4ZWNPcW5ESThHT2hJR0NJcVpVbjhTaGRNL3lIamhRMk1oMEhqM1UwTGxLdm5tZkdTUWwKICAgICAgICAgICAgICBqMHZpR3diRkNhTmFJUDN6YzVVbUNyZEU1aDhzV0wzRnU3SUxLTTlSeUZhMklMSHJKU2NWOXQ2MjNJY0hmZkhQCiAgICAgICAgICAgICAgSWVhWS9XdHVhcHNycVJGeHVRTDlRRldOMEZzUklkTG1qVHErMDArQi9Ybm5LUktGQnVXZmpoSExGL3V1OGYrRQogICAgICAgICAgICAgIHQ2TGYyM0tiOHlENlpSN2RpaE1aQUdIbllRL2hsaE09CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kczpYNTA5Q2VydGlmaWNhdGU+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2RzOlg1MDlEYXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgIDwvZHM6S2V5SW5mbz4KCiAgICAgICAgICAgICAgICAgICAgICA8L0tleURlc2NyaXB0b3I+CiAgICAgICAgICAgICAgICAgICAgICA8S2V5RGVzY3JpcHRvciB1c2U9InNpZ25pbmciPgogICAgICAgICAgICAgICAgICAgICAgICAgIDxkczpLZXlJbmZvPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRzOlg1MDlEYXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkczpYNTA5Q2VydGlmaWNhdGU+CiAgICAgICAgICAgICAgTUlJREZEQ0NBZnlnQXdJQkFnSVZBTjN2ditiN0tONVNlOW0xUlpzQ2xscC9CL2hkTUEwR0NTcUdTSWIzRFFFQgogICAgICAgICAgICAgIEN3VUFNQlV4RXpBUkJnTlZCQU1NQ21sa2NIUmxjM1JpWldRd0hoY05NVFV4TWpFeE1ESXlNREUwV2hjTk16VXgKICAgICAgICAgICAgICBNakV4TURJeU1ERTBXakFWTVJNd0VRWURWUVFEREFwcFpIQjBaWE4wWW1Wa01JSUJJakFOQmdrcWhraUc5dzBCCiAgICAgICAgICAgICAgQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBaDkxY2FlWTBRODV1aGFVeXFGd1AyYk1qd01GeE16UmxBb3FCSGQ3ZwogICAgICAgICAgICAgIHU2ZW80ZHVhZUx6MUJhb1IyWFRCcE5OdkZSNW9ISCtUa0thaFZER2VINStrY25JcHhJOEpQZHNabWwxc3J2ZjIKICAgICAgICAgICAgICBaNmR6SnN1bEpaVWRwcW5uZ3ljVGtHdFpnRW9DMXZtWVZreTJCU0FJSWlmbWRoNnMwZXBiSG5NR0xzSHpNS2ZKCiAgICAgICAgICAgICAgQ2IvUTZkWXpSV1RDUHR6RTJWTXVRcXFXZ2V5TXI3dTE0eC9WcXI5UlBFRnNnWThHSXU1anpCNkF5VUl3ckxnKwogICAgICAgICAgICAgIE1Oa3Y2YUlkY0h3eFlUR0w3aWpmeTZyU1dyZ0JmbFFvWVJZTkVuc2VLMFpIZ0phaHo0b3ZDYWc2d1pBb1BwQnMKICAgICAgICAgICAgICB1WWxZN2xFcjg5VWNiNk5IeDN1cUdNc1hsREZkRTRRd2ZETExoQ1lIUHZKMHV3SURBUUFCbzFzd1dUQWRCZ05WCiAgICAgICAgICAgICAgSFE0RUZnUVVBa09nRUQzaVlkbXZRRU9NbTZ1L0ptRC9VVFF3T0FZRFZSMFJCREV3TDRJS2FXUndkR1Z6ZEdKbAogICAgICAgICAgICAgIFpJWWhhSFIwY0hNNkx5OXBaSEIwWlhOMFltVmtMMmxrY0M5emFHbGlZbTlzWlhSb01BMEdDU3FHU0liM0RRRUIKICAgICAgICAgICAgICBDd1VBQTRJQkFRQklkZDRZV2xudkpqcWw4K3pLS2dtV2dJWTdVOERBOGU2UWNiQWY4ZjhjZEUzM1JTbmpJNjNYCiAgICAgICAgICAgICAgc3YveTlHZm1iQVZBRDZSSUFYUEZGZVJZSjA4R094R0k5YXhmTmFLZGxza2xKOWJrNGR1Y0hxZ0NTV1lWZXIzcwogICAgICAgICAgICAgIFJRQmp4eU9mU1R2azlZQ0p2ZEpWUVJKTGNDdnh3S2FrRkNzT1NuVjN0OU92Tjg2QWsrZktQVkI1ajJmTS8wZloKICAgICAgICAgICAgICBLcWpuM2lxZ2ROUFRMWFBzdUpMSk81bElUUmlCYTRvbm1WZWxBaUNzdEk5UFFpYUVjaytvQUhuTVRuQzlKRS9CCiAgICAgICAgICAgICAgREh2M2U0cndxM0x6bmxxUHcwR1NkN3hxTlRkTUR3Tk9Xamt1T3Izc0dwV1M4bXMvWkhIWFYxVmQyMnVQZTcwaQogICAgICAgICAgICAgIHMwMHhydjE0ekxpZmNjOG9qNURZek9oWVJpZlJYZ0hYCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kczpYNTA5Q2VydGlmaWNhdGU+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2RzOlg1MDlEYXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgIDwvZHM6S2V5SW5mbz4KCiAgICAgICAgICAgICAgICAgICAgICA8L0tleURlc2NyaXB0b3I+CiAgICAgICAgICAgICAgICAgICAgICA8S2V5RGVzY3JpcHRvciB1c2U9ImVuY3J5cHRpb24iPgogICAgICAgICAgICAgICAgICAgICAgICAgIDxkczpLZXlJbmZvPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRzOlg1MDlEYXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkczpYNTA5Q2VydGlmaWNhdGU+CiAgICAgICAgICAgICAgTUlJREV6Q0NBZnVnQXdJQkFnSVVHNk5uMXJsRVJTMXZzaTg4dGNkelNZWDBvcUF3RFFZSktvWklodmNOQVFFTAogICAgICAgICAgICAgIEJRQXdGVEVUTUJFR0ExVUVBd3dLYVdSd2RHVnpkR0psWkRBZUZ3MHhOVEV5TVRFd01qSXdNVFJhRncwek5URXkKICAgICAgICAgICAgICBNVEV3TWpJd01UUmFNQlV4RXpBUkJnTlZCQU1NQ21sa2NIUmxjM1JpWldRd2dnRWlNQTBHQ1NxR1NJYjNEUUVCCiAgICAgICAgICAgICAgQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUNCWHYwbzNmbVQ4aWx1eUxqSjRsQkFWQ1crWlJWeUVYUFlRdVJpN3ZmRAogICAgICAgICAgICAgIGNPNGE2ZDFreGlKTHNhSzBXODhWTnhqRlFScjhQZ0RrV3IyOHZ3b0gxcmdrNHBMc3N6TEQ0OERCekQ5NDJwZUoKICAgICAgICAgICAgICBsL1M2Rm5zSUpqbWFIY0JoNHBiTmhVNHlvd3U2M2lLa3Z0dHJjWkFFYnBFcm82WjhDemlXRXg4c3l3b2FZRVFHCiAgICAgICAgICAgICAgaWZQa3I5T1JWNkNuM3R4cSs5Z01CZVBHNDFHcnRaclVHSXUreHJuZEwwU2hoNFBxMGVxLzlNQXNWbElJWEVhOAogICAgICAgICAgICAgIDlXZkg4SjJrRmNUT2ZvV3RJYzcwYjdUTFpRc3g0WW5OY25yR0xTVUVjc3RGeVBMWCtYdHY1U05aRjg5T09JeFgKICAgICAgICAgICAgICBWTmpOdmdFNURiSmI5aE1NNFVBRnFJKzFibzlRcXR4d1RoamMvc092SXh6TkFnTUJBQUdqV3pCWk1CMEdBMVVkCiAgICAgICAgICAgICAgRGdRV0JCU3RUeW9nUlB1QVZHNnE3eVB5YXYxdXZFKzdwVEE0QmdOVkhSRUVNVEF2Z2dwcFpIQjBaWE4wWW1WawogICAgICAgICAgICAgIGhpRm9kSFJ3Y3pvdkwybGtjSFJsYzNSaVpXUXZhV1J3TDNOb2FXSmliMnhsZEdnd0RRWUpLb1pJaHZjTkFRRUwKICAgICAgICAgICAgICBCUUFEZ2dFQkFGTWZvT3Yrb0lTR2p2YW1xNytZNEc3ZXA1dnhsQVBlSzNSQVRZUFl2QW15SDk0NnFaWGg5OG5pCiAgICAgICAgICAgICAgUVh5dXFaVzVQNWVFdDg2dG9ZNDVJd0RVNXIwOVNLd0h1Z2hFZTk5aWlFa3hoMG1iMnFvODRxWDkvcWNnK2t5TgogICAgICAgICAgICAgIGplTGQvT1N5b2xwVUNFRk53T0Zjb2c3cGo3RWVyKzZBSGJ3VG4xTWpiNVRCc0t3dERNSnNheFB2ZGowdTdNNXIKICAgICAgICAgICAgICB4TC93SGtGaG4xckNvMlFpb2p6alNsVjN5TFRoNDlpVHloRTNjRytSeGFOS0RDeGhwMGpTU0xYMUJXL1pvUEE4CiAgICAgICAgICAgICAgK1BNSkVBK1EwUWJ5UkQ4YUpPSE41TzhqR3hDYS9aemNPbllWTDZBc0VYb0RpWTN2QVVZaDFGVW9uT1d3MG05SAogICAgICAgICAgICAgIHArdEdVYkdTMmw4NzNKNVByc2JwZUtFVlIvSUlvS289CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kczpYNTA5Q2VydGlmaWNhdGU+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2RzOlg1MDlEYXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgIDwvZHM6S2V5SW5mbz4KCiAgICAgICAgICAgICAgICAgICAgICA8L0tleURlc2NyaXB0b3I+CgogICAgICAgICAgICAgICAgICAgICAgPEF0dHJpYnV0ZVNlcnZpY2UgQmluZGluZz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6MS4wOmJpbmRpbmdzOlNPQVAtYmluZGluZyIgTG9jYXRpb249Imh0dHBzOi8vaWRwdGVzdGJlZDo4NDQzL2lkcC9wcm9maWxlL1NBTUwxL1NPQVAvQXR0cmlidXRlUXVlcnkiLz4KICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPEF0dHJpYnV0ZVNlcnZpY2UgQmluZGluZz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmJpbmRpbmdzOlNPQVAiIExvY2F0aW9uPSJodHRwczovL2lkcHRlc3RiZWQ6ODQ0My9pZHAvcHJvZmlsZS9TQU1MMi9TT0FQL0F0dHJpYnV0ZVF1ZXJ5Ii8+IC0tPgogICAgICAgICAgICAgICAgICAgICAgPCEtLSBJZiB5b3UgdW5jb21tZW50IHRoZSBhYm92ZSB5b3Ugc2hvdWxkIGFkZCB1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wgdG8gdGhlIHByb3RvY29sU3VwcG9ydEVudW1lcmF0aW9uIGFib3ZlIC0tPgoKICAgICAgICAgICAgICAgICAgPC9BdHRyaWJ1dGVBdXRob3JpdHlEZXNjcmlwdG9yPgoKICAgICAgICAgICAgICA8L0VudGl0eURlc2NyaXB0b3I+</xml>
            </metadata>
            <skipSslValidation>true</skipSslValidation>
            <linkText>Shibboleth</linkText>
            <authenticationRequestBinding>urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST</authenticationRequestBinding>
            <nameOfUsernameAttribute>uid</nameOfUsernameAttribute>
        </provider>
    </serviceProvider>
</saml2>

Sequence

...

Configuration

Sequence contains follow following attributes: 

NameDescriptionRequiredType
nameUnique name of the authentication sequence. This name is fact a short identifier. It is supposed to give some idea about purpose of the sequence to system administrator. But it is not supposed to be used as a user-friendly label. Sequence name must be unique.trueString
descriptionFree form description of the sequence (administrator comment).falseString
channelSpecification of channel for authentication sequence.falseAuthenticationSequenceChannelType
requireAssignmentTargetRequired assignment target. This authentication sequence is applicable only to users that have active assignment with this target (and relation). If the sequence is attempted on a user that does not have this assignment then the authentication will fail.falseObjectReferenceType
nodeGroupRequired node group. This authentication sequence is applicable only to node group that have active assignment with this archetype.falseObjectReferenceType
moduleSpecification of authentication module in the sequence.trueAuthenticationSequenceModuleType

...

Channel specification for authentication sequence. It specifies whether this sequence is usable for a specific channel (user/GUI, REST, etc.) AuthenticationSequenceChannelType contains follow following attributes:

NameDescriptionRequiredType
channelIdName (URI) of the channel.trueString
descriptionFree form description (administrator comment).falseString
defaultSpecifies whether this sequence is the default sequence for a specified channel. The default sequence will be chosen in case that specific sequence was not requested, e.g. by using URL suffix. If this element is not present and only a single sequence is defined for a channel, then such sequence is considered to be the default. If more than one sequence is specified then none of them is considered to be default. In that case this element must be used explicitly.falseboolean
urlSuffixURL suffix that can be used to select this authentication sequence specifically.falsetrueString

AuthenticationSequenceModuleType

Specification of authentication module in the sequence. The authentication modules are evaluated in sequence (or in parallel if possible). At least one authentication module must succeed for authentication to be successful. If there are required or requisite modules in the sequence then all of them must succeed for the sequence to be successful. AuthenticationSequenceModuleType contains follow following attributes:

NameDescriptionRequiredType
nameReference to the authentication module name. Value of this element must match name of existing authentication module.trueString
descriptionFree form description (administrator comment).falseString
orderOrdering number for the module. The modules are sorted according to those numbers.false100
necessityNecessity, i.e. the level of requirement, whether the module is mandatory or optional. We support only SUFFICIENT modules in 4.1.falseSUFFICIENT

...

Code Block
languagexml
titleExample of default sequence
linenumberstrue
<sequence>
	<name>admin-gui-default</name>
    <description>
    	Default GUI authentication sequence.
        We want to try company SSO, federation and internal. In that order.
        Just one of then need to be successful to let user in.
    </description>
    <channel>
    	<channelId>http://midpoint.evolveum.com/xml/ns/public/modelcommon/channels-3#user</channelId>
        <default>true</default>
		<urlSuffix>default</urlSuffix>
    </channel>
	<nodeGroup oid="05b6933a-b7fc-4543-b8fa-fd8b278ff9ee" relation="org:default" type="c:ArchetypeType"/>
    <module>
    	<name>mySamlSso</name>
        <order>30</order>
        <necessity>sufficient</necessity>
    </module>
    <module>
    	<name>internalLoginForm</name>
        <order>20</order>
        <necessity>sufficient</necessity>
    </module>
</sequence>

...

Code Block
languagexml
titleExample of sequence for administrator login
linenumberstrue
<sequence>
	<name>admin-gui-emergency</name>
    <description>
    	Special GUI authentication sequence that is using just the internal user password.
        It is used only in emergency. It allows to skip SAML authentication cycles, e.g. in case
        that the SAML authentication is redirecting the browser incorrectly.
    </description>
    <channel>
    	<channelId>http://midpoint.evolveum.com/xml/ns/public/modelcommon/channels-3#user</channelId>
        <default>false</default>
        <urlSuffix>emergency</urlSuffix>
    </channel>
    <requireAssignmentTarget oid="00000000-0000-0000-0000-000000000004" relation="org:default" type="c:RoleType">
    <!-- Superuser -->
    </requireAssignmentTarget>
    <module>
    	<name>internalLoginForm</name>
        <order>1</order>
        <necessity>sufficient</necessity>
    </module>
</sequence>

Ignored path Configuration

Tag <authentication> contains tag <ignoredLocalPath>, which defines path without authentication. For example:

Code Block
<authentication>
	.
	.	
	.
	<ignoredLocalPath>/actuator</ignoredLocalPath>
	<ignoredLocalPath>/actuator/health</ignoredLocalPath>
</authentication>

Complete Configuration Examples

You can find example on security-policy-flexible-authentication.

Limitations

Those are the limitations of current implementation of flexible authentication mechanisms.

  • Configuration schema for flexible authentication is designed to be mostly complete. However, not all configuration options are currently supported.
  • Flexible authentication is currently supported only for midPoint administration GUI. Only internal password authentication and SAML2 is officially supported. The rest of the functionality is considered to be experimental.
  • OpenID Connect protocol is not supported yet.
  • Social login functionality is not supported yet.
  • It is unlikely that midPoint could be used as a member of identity federation directly. Identity proxy or a similar technology may be needed.
  • Authentication configuration is global. Only global security policy can be used to configure the authentication (i.e. security policy referenced directly from system configuration object). Per-organization security policies or any other security policies cannot be used.
  • Support for authentication module necessity is limited. We support only SUFFICIENT modules in 4.1.
  • Authentication modules for SOAP web services are not supported because SOAP is deprecated and it will be removed soon.
  • REST service supports HTTP basic authentication only. Distributed authentication protocols (OpenID Connect, SAML) are not supported yet. REST support for flexible authentication is experimental.
  • Even though the authentication configuration often suggests that there may be more than one instances of credentials (password, nonce), midPoint currently supports only a single password, single nonce and a single set of security questions. Multiple credentials are not supported. The reason for mentioning credential names the configuration schema is to have ability to extend midPoint functionality in the future.

The implementation can be improved in the future. Please see Flexible Authentication Improvements for the details.

See Also