Table Of Contents

Previous topic

6.4. Connection information

Next topic

7. MFA Client

6.5. AAPlugin

6.5.1. AAPlugin way of working

When SPS calls the AAPlugin, it does so by creating an AAPlugin (or more likely derived class) instance. The initialization of the instance processes the given plugin configuration and sets the logging level appropriately.

On the new AAPlugin instance SPS will make a call to authenticate, authorize or session_ended. In all cases AAPlugin first collects the input parameters in self.connection and sets up self.cookie and self.session_cookie attributes.

In case of authenticate the prescribed steps in AAPlugin._authentication_steps() are executed, including the user defined AAPlugin.do_authenticate() and if all was successful then the steps in AAPlugin._post_successful_authentication_steps() are also executed. The later steps can ask further questions from the user and do other housekeeping tasks.

In case of authorize the prescribed steps in AAPlugin._authorization_steps() are executed, where the last step is a call to the user defined AAPlugin.do_authorize().

In case of session_ended the prescribed steps in AAPlugin._session_ended_steps() are executed, where the last step is a call to the user defined AAPlugin.do_session_ended().

If a step returns with a verdict such as accept, deny or need info, then AAPlugin will add values stored in self.cookie and self.session_cookie to the verdict and return the result to SPS.

If a step returns with None, then AAPlugin marks it as done, and does not call it again in case the plugin returns need info and the plugin is invoked again with the same callback.

6.5.2. AAPlugin methods and attributes

class safeguard.sessions.plugin.aa_plugin.AAPlugin(configuration, defaults=None, logger=None)

The AAPlugin class implements the common functionality of AA plugins. The following methods and attributes are available outside the constructor - on top of the ones inherited from PluginBase <safeguard.sessions.plugin.plugin_base.PluginBase class:

connection

The self.connection provides a read-only view of the parameters passed to the currently executing plugin hook, e.g. do_authenticate().

cookie

The self.cookie attribute is a dict that retains its contents between invocations of do_authenticate(), do_authorize() and do_session_ended(). This is the way to pass data between these functions.

When the plugin returns the contents are automatically returned to SPS. Note that when AAResponse.with_cookie is used, it takes precedence and updates self.cookie before returning to SPS.

The self.session_cookie is similar to self.cookie, but it is also visible in other plugins in the same session. When the plugin returns the contents are automatically returned to SPS. Note that when AAResponse.with_session_cookie is used, it takes precedence and updates self.session_cookie before returning to SPS.

username

The self.username is a @cookie_property which is equal to the gateway user name, or if not present, then the target user name, or finally the username value in the key_value_pairs. If none of these are present then the connection is automatically denied as we don’t have a user name to work with.

The initial value of self.username is calculated by _extract_username(). As a cookie property, the value of self.username is retained in subsequent invocations of the plugin.

mfa_identity

The self.mfa_identity is a @cookie_property which is equal to self.username after mapping and transformations to the multi factor authentication identity.

As a cookie property, the value of self.mfa_identity is retained in subsequent invocations of the plugin.

mfa_password

The self.mfa_password is read-only property that is implemented by _extract_mfa_password().

do_authenticate()

The do_authenticate() method should verify that the given MFA identity (self.mfa_identity) matches the given MFA password (self.mfa_password). In case the password is an empty string, the check should do a challenge-response or push notification or some other check. For details consult the Creating custom Authentication and Authorization plugins technical document.

Returns

dict with at least the key ‘verdict’ to indicate ‘ACCEPT’, ‘DENY’ or ‘NEEDINFO’

do_authorize()

The do_authorize() method should verify that the given MFA identity (self.mfa_identity) has authority (has the right) to access the given target asset (self.connection.target_user, self.connection.target_server, etc). For details consult the Creating custom Authentication and Authorization plugins technical document.

Returns

dict with at least the key ‘verdict’ to indicate ‘ACCEPT’, ‘DENY’.

do_session_ended()

The do_session_ended() hook can be used to send a log message related to the entire session or close the ticket related to the session if the plugin interacts with a ticketing system. For details consult the Creating custom Authentication and Authorization plugins technical document.

Returns

None

_authentication_steps()

The _authentication_steps() function returns a list of other functions to be called to execute the authentication task. The default implementation is as follows:

    def _authentication_steps(self):
        """
        The :meth:`_authentication_steps` function returns a list of other functions to be called to execute the
        authentication task. The default implementation is as follows:

        .. literalinclude:: ../../../../src/safeguard/sessions/plugin/aa_plugin.py
            :pyobject: AAPlugin._authentication_steps
        """

        yield self._check_username
        yield self._check_user_list_whitelist
        yield self._check_ldap_group_whitelist
        yield self._check_authentication_cache
        yield self._map_username_explicit
        yield self._map_username_ldap
        yield self._transform_username
        yield self._ask_mfa_password
        yield self._log_authenticate_calculated_mfa_identity
        yield self.do_authenticate
_post_successful_authentication_steps()

The _post_successful_authentication_steps() function returns a list of other functions to call be called after _authentication_steps() in case of successful authentication. The functions listed here may only return None or a AAResponse.need_info reply. The default implementation is as follows:

    def _post_successful_authentication_steps(self):
        """
        The :meth:`_post_successful_authentication_steps` function returns a list of other functions to call be called
        after :meth:`_authentication_steps` in case of successful authentication. The functions listed here may only
        return ``None`` or a
        :meth:`AAResponse.need_info <safeguard.sessions.plugin.plugin_response.AAResponse.need_info>` reply.
        The default implementation is as follows:

        .. literalinclude:: ../../../../src/safeguard/sessions/plugin/aa_plugin.py
            :pyobject: AAPlugin._post_successful_authentication_steps
        """

        yield self._refresh_authentication_cache
        yield self._ask_questions
_authorization_steps()

The _authorization_steps() function returns a list of other functions to call to finish the authentication task. The default implementation is as follows:

    def _authorization_steps(self):
        """
        The :meth:`_authorization_steps` function returns a list of other functions to call to finish the authentication
        task. The default implementation is as follows:

        .. literalinclude:: ../../../../src/safeguard/sessions/plugin/aa_plugin.py
            :pyobject: AAPlugin._authorization_steps
        """

        yield self._log_authorize_calculated_mfa_identity
        yield self._check_and_increase_client_connection_count
        yield self.do_authorize
_session_ended_steps()

The _session_ended_steps() function returns a list of other functions to call to finish the session_ended task. The functions in the list must return with None. The default implementation is as follows:

    def _session_ended_steps(self):
        """
        The :meth:`_session_ended_steps` function returns a list of other functions to call to finish the session_ended
        task. The functions in the list must return with None. The default implementation is as follows:

        .. literalinclude:: ../../../../src/safeguard/sessions/plugin/aa_plugin.py
            :pyobject: AAPlugin._session_ended_steps
        """

        yield self._decrease_client_connection_count
        yield self.do_session_ended
_extract_username()

The _extract_username() method may be overridden to modify the calculation of the gateway username. For example to introduce a new key_value_pair that can be the source of the username.

If this method returns None, then AAPlugin automatically denies the connection.

Returns

str or None

_map_username_explicit()

The _map_username_explicit() method is implementing the [usermapping source=explicit] section in the configuration. It may alter the value of self.mfa_identity.

_map_username_ldap()

The _map_username_ldap() method is implementing the [usermapping source=ldap_server] section in the configuration. It may alter the value of self.mfa_identity.

_transform_username()

The _transform_username() method is implementing the [username_transform] section in the configuration. It may alter the value of self.mfa_identity.

_check_username()

The _check_username() method checks that the plugin received a user identity to work with. It should return AAResponse.deny verdict if there is no username, otherwise None.

_extract_mfa_password()

The _extract_mfa_password() method returns the value of self.connection.key_value_pairs['otp']. The value is either specified as part of the user name or if not, then AAPlugin will ask the user for it interactively.

The _extract_mfa_password() method may be overwritten to modify the calculation of the MFA password. For example to introduce a new key_value_pair that can be the source of the password.

If this method returns None, then AAPlugin automatically asks for the password.

Returns

str or None

authenticate(cookie, session_cookie, **kwargs)

Should not be modified.

The authenticate() function is called by SPS directly. Should not be modified, see do_authenticate() for customization.

authorize(cookie, session_cookie, **kwargs)

Should not be modified.

The authorize() function is called by SPS directly. Should not be modified, see do_authorize() for customization.

session_ended(session_id, cookie, session_cookie)

Should not be modified.

The session_ended() function is called by SPS directly. Should not be modified, see do_session_ended() for customization.

_add_gateway_user(verdict)

An ACCEPT verdict should return the username that was actually authenticated as gateway user. This function will use the actual self.username in the return value, unless already set by do_authenticate.

Parameters

verdict – an ACCEPT verdict

Returns

updated verdict