<chapter id="authentication-spi">
    <title>Authentication SPI</title>
    <para>
        Keycloak provides Authentication SPI, which allows to choose the <literal>AuthenticationProvider</literal> for authenticating users.
        AuthenticationProvider is the interface, which states how will be your usernames/passwords validated. You can choose from
        the set of available AuthenticationProviders or you can even implement and plug your own AuthenticationProvider, which
        will allow to provide your own way how will Keycloak validates users and their passwords.
    </para>
    <section id="authentication-available-providers">
        <title>Available Authentication Providers</title>
        <para>
            <itemizedlist>
                <listitem><literal>Model</literal> - This provider validates users and their passwords based on the Keycloak model. So it just delegates
                    to model implementation provided either by RDBMS or Mongo at this moment. This is default AuthenticationProvider,
                    which is configured for <literal>keycloak-admin</literal> realm by default and it's also automatically configured for newly created realms.
                </listitem>
                <listitem><literal>External-model</literal> - This provider also uses Keycloak model, but it uses different realm to validate your users against.
                    For example if you want to create new realm "foo" and you want all users of already existing realm "bar" that they are automatically
                    able to login into realm "foo" with their usernames and passwords, you can choose this provider.
                </listitem>
                <listitem><literal>Picketlink</literal> - This provider delegates Authentication to <ulink url="http://docs.jboss.org/picketlink/2/latest/reference/html-single/#chap-Identity_Management_-_Overview">Picketlink IDM</ulink>
                    framework. Right now, Picketlink IDM in Keycloak is configured to always use LDAP based Identity store, which means that picketlink provider
                    allows you to authenticate your users against LDAP server. Note that you will first need to configure LDAP server as described
                    <link linkend="ldap">here</link> . <literal>PicketlinkAuthenticationProvider</literal> configured for the realm will automatically use LDAP configuration for this realm.
                </listitem>
            </itemizedlist>
        </para>
    </section>
    <section id="authentication-features">
        <title>Features and configuration</title>
        <para>
            <itemizedlist>
                <listitem>
                    You can configure AuthenticationProviders separately for each realm. So for example you can choose that just realm
                    "foo" will use <literal>PicketlinkAuthenticationProvider</literal> and authenticate users against LDAP but realm "keycloak-admin" will still use default <literal>ModelAuthenticationProvider</literal>.
                </listitem>
                <listitem>
                    There is also possibility to choose more authentication providers for the realm, which actually means that Keycloak
                    will use first available AuthenticationProvider and just in case that user doesn't exist here,
                    it will fallback to second AuthenticationProvider in chain. So this may allow for example scenario, in which
                    you authenticate user against Keycloak database (model) and just if he doesn't exist in database, it will fallback to LDAP (picketlink).
                </listitem>
                <listitem>
                    You can configure for each AuthenticationProvider if you want to update passwords - option <literal>passwordUpdateSupported</literal>.
                    This means that when user update password or his profile through Keycloak UI, this change will be propagated into AuthenticationProvider.
                    So for example password in LDAP will be updated if it's <literal>true</literal>, but for read-only LDAP, you will likely switch it to <literal>false</literal>.
                    It also means that newly registered users will be propagated to particular AuthenticationProvider too,
                    but note that each user is always bind just to one AuthenticationProvider.
                </listitem>
                <listitem>
                    You can add/edit/remove AuthenticationProviders in the <literal>Authentication</literal> tab in admin console, which is under URL
                    <ulink url="http://localhost:8080/auth/admin/keycloak-admin/console/#/realms/YOUR_REALM/auth-settings">http://localhost:8080/auth/admin/keycloak-admin/console/#/realms/YOUR_REALM/auth-settings</ulink>
                </listitem>
            </itemizedlist>

        </para>
    </section>
    <section id="authentication-new-provider">
        <title>Creating your own Authentication Provider</title>
        <para>
            You need to implement interface AuthenticationProvider and add the name of your AuthenticationProviderFactory class into
            <literal>META-INF/services/org.keycloak.authentication.AuthenticationProviderFactory</literal> file inside your JAR with AuthenticationProvider. You also need to copy this JAR into
            <literal>standalone/deployments/auth-server.war/WEB-INF/lib</literal> . The best is to look at <ulink url="https://github.com/keycloak/keycloak/tree/master/examples/providers/authentication-properties">example</ulink> and try it out.
        </para>
    </section>
</chapter>