The authenticate method performs the authentication of the session and returns a verdict that determines if SPS permits the connection to continue to the target server.
def authenticate(self, session_id, protocol, connection_name, client_ip, client_port, key_value_pairs): return { 'verdict': 'ACCEPT', 'additional_metadata': 'my_metadata', 'my_key': 'my_value', }
You must implement the authenticate method in the plugin.
TIP: If you do not want to do anything in this method, include an empty method that returns the ACCEPT verdict.
def authenticate (self): return { 'verdict': 'ACCEPT', }
In addition, no gateway authentication has been performed by the plugin if the authenticate method returns:
The order of the arguments does not make a difference, only their names do. Every argument is optional.
session_id
Type: string |
Description: The unique identifier of the session.
cookie
Type: dictionary |
Description: The cookie returned by the previous hook in the session. If this is the first call for that session, it is initialized as an empty dictionary, otherwise it has the value returned by one of the previous calls in this particular AA plugin. You can use the cookie to maintain the state for each particular connection or to transfer information between the different methods of the plugin. For an example that transfers information in the cookie between two methods, see Examples.
session_cookie
Type: dictionary |
Description: You can use the session cookie to maintain global state between plugins for each particular connection. If this is the first call for that session, it is initialized as an empty dictionary, otherwise it has the value returned by a previous plugin hook in the session.
connection_name
Type: string |
Description: The name of the Connection policy that handles the client's connection request.
client_hostname
Type: string |
Description: A string containing the hostname of the client, if DNS lookup has been successful. If not, the value of this parameter is None.
client_ip
Type: string |
Description: A string containing the IP address of the client.
client_port
Type: int |
Description: The port number of the client.
gateway_user
Type: string |
Description: Contains the gateway username of the client if already available (for example, if the user performed inband gateway authentication), otherwise its value is None.
key_value_pairs
Type: dictionary |
Description: A dictionary containing plugin-specific information (for example, it may include a token ID). This dictionary also contains any key-value pairs that the user specified. In the plugin, such fields are already parsed into separate key-value pairs. For details on how the user can provide such data during a connection, see "Integrating external authentication and authorization systems" in the Administration Guide.
protocol
Type: string |
Description: The protocol used in the connection that the plugin is currently processing. Enter one of the following values: rdp, ssh, telnet.
target_username
Type: string or None |
Description: Contains information about the target username if already available (for example, if the user performed inband gateway authentication), otherwise its value is None.
The method must return a dictionary with the following (required or optional) elements.
The required elements are:
verdict, which must contain one of the following returned values:
ACCEPT, which returns gateway_user and gateway_groups together.
NEEDINFO, which returns question.
The optional elements are:
The elements in more detail:
verdict
Type: string |
Required: yes |
Description: Must contain one of the following values:
ACCEPT:The authentication was successful, the client can continue the connection
If the plugin returns both gateway_users and gateway_groups elements, it means that gateway authentication has been performed.
For example, the following sample code rejects the connection.
return {'verdict': 'DENY'}
cookie
Type: dictionary |
Required: no |
Description: The cookie returned by the previous hook in the session. If this is the first call for that session, it is initialized as an empty dictionary, otherwise it has the value returned by one of the previous calls in this particular AA plugin. You can use the cookie to maintain the state for each particular connection or to transfer information between the different methods of the plugin. For an example that transfers information in the cookie between two methods, see Examples.
session_cookie
Type: dictionary |
Required: no |
Description: You can use the session cookie to maintain global state between plugins for each particular connection. If this is the first call for that session, it is initialized as an empty dictionary, otherwise it has the value returned by a previous plugin hook in the session.
additional_metadata
Description: The value of this string will be stored in the Additional metadata column of the SPS connection database, and will be available on the SPS search interface.
gateway_user
Type: string |
Required: no |
gateway_groups
Type: list |
Required: no |
Description: Optionally, the plugin can return the gateway_user and gateway_groups values. SPS will only update the gateway username and gateway groups fields in the connection database if the plugin returns the gateway_user and gateway_groups values. The returned gateway_user and gateway_groups values override any such attributes already available on SPS about the connection (which means that channel policy evaluations will be affected), so make sure that the plugin uses the original values appropriately.
NOTE: If the plugin returns the gateway_user and gateway_groups values, you may have to configure an appropriate Usermapping Policy in the Connection Policy. If the plugin returns a gateway_user that is different from the remote user, the connection will fail without a Usermapping Policy. For details on Usermapping Policies, see "Configuring usermapping policies" in the Administration Guide.
For example, the following sample code accepts the connection and sets the gateway_user and gateway_groups fields. (Naturally, you should write the plugin code that actually retrieves these data from the third-party system.) For details, see Examples.
return { 'verdict': 'ACCEPT', 'gateway_user': 'username-received-from-third-party', 'gateway_groups': [ 'usergroup1-received-from-third-party', 'usergroup2-received-from-third-party' ] }
question
Type: tuple |
Required: no |
Description: A tuple that contains key-question pairs and optionally a third element to disable echoing. You can use it to request additional information from the client when using the NEEDINFO verdict in RDP, Telnet, and SSH connections. For example, the following sample code displays a prompt (in this case, Enter your token number) to the user. For details, see Examples.
return { 'verdict': 'NEEDINFO', 'question': ('token', 'Enter your token number: ') }
If the optional third element is True, the answer will not be echoed to the client.
TIP: Set the third element to True if the answer to the question is sensitive information (for example, a password).
return { 'verdict': 'NEEDINFO', 'question': ('token', 'Enter your token number: ', True) }
Note that in SPS version 4.3.0 and 4.3.1, question was a dictionary. Starting with version 4.3.2, it is a tuple.
To request additional information from the client (for example, a one-time password from a token, or a ticket ID), the authenticate method may return the NEEDINFO verdict and the question tuple containing key-question pairs. The questions are asked from the user in a protocol-specific way and the authenticate method is called again with a key_value_pairs argument containing the answers in key-answer pairs, where the key belongs to the corresponding question. Alternatively, you can also use the cookie to supply additional information to the plugin.
The authorize method performs the authorization of the session and returns a verdict that determines if SPS permits the connection to continue to the target server. This method is executed only once. SPS executes the authorize method after the authentication method, and any inband gateway authentication or inband destination selection steps. As a result, the authorize method already has access to the IP address of the target server and the remote username (the username used in the server-side connection). You must implement the authorize method in the plugin.
TIP: If you do not want to do anything in this method, include an empty method that returns the ACCEPT verdict. Otherwise, the connection will fail with the following log message: Calling Authorize hook of AA plugin failed..
def authorize (self): return {'verdict': 'ACCEPT'}
The order of the arguments does not make a difference, only their names do. Every argument is optional.
session_id
Type: string |
Description: The unique identifier of the session.
cookie
Type: dictionary |
Description: The cookie returned by the previous hook in the session. If this is the first call for that session, it is initialized as an empty dictionary, otherwise it has the value returned by one of the previous calls in this particular AA plugin. You can use the cookie to maintain the state for each particular connection or to transfer information between the different methods of the plugin. For an example that transfers information in the cookie between two methods, see Examples.
session_cookie
Type: dictionary |
Description: You can use the session cookie to maintain global state between plugins for each particular connection. If this is the first call for that session, it is initialized as an empty dictionary, otherwise it has the value returned by a previous plugin hook in the session.
connection_name
Type: string |
Description: The name of the Connection Policy that handles the client's connection request.
client_hostname
Type: string |
Description: A string containing the hostname of the client, if DNS lookup has been successful. If not, the value of this parameter is None.
client_ip
Type: string |
Description: A string containing the IP address of the client.
client_port
Type: int |
Description: The port number of the client.
gateway_groups
Type: string list |
Description: The final gateway groups of the gateway user.
key_value_pairs
Type: dictionary |
Description:
A dictionary containing plugin-specific information (for example, it may include the username).
This dictionary also contains any key-value pairs that the user specified when establishing the connection. In the plugin, such fields are already parsed into separate key-value pairs. For details on how the user can provide such data during a connection, see "Integrating external authentication and authorization systems" in the Administration Guide.
protocol
Type: string |
Description: The protocol used in the connection that the plugin is currently processing. Enter one of the following values: rdp, ssh, telnet.
client_port
Type: int |
Description: The port number of the client.
target_server - DEPRECATED
Type: string or None |
Description: This parameter is DEPRECATED. Use server_ip instead. Contains information about the target server if already available (for example, if the user performed inband gateway authentication), otherwise its value is None.
server_ip
Type: string or None |
Description: Contains information about the target server if already available (for example, if the user performed inband gateway authentication), otherwise its value is None.
target_port - DEPRECATED
Type: integer or None |
Description: This parameter is DEPRECATED. Use server_port instead. Contains information about the target port if already available (for example, if the user performed inband gateway authentication), otherwise its value is None.
server_port
Type: integer or None |
Description: Contains information about the target port if already available (for example, if the user performed inband gateway authentication), otherwise its value is None.
target_username - DEPRECATED
Type: string |
Description: This parameter is DEPRECATED. Use server_username instead. The username SPS uses to authenticate on the target server.
server_username
Type: string |
Description: The username SPS uses to authenticate on the target server.
server_hostname
Type: string |
Description: A string containing the hostname of the server, if DNS lookup has been successful. If not, the value of this parameter is None.
The method must return a dictionary with the following (required or optional) elements.
The required elements are:
verdict, which must contain one of the following returned values:
ACCEPT, which indicates that the authentication was successful and the client can continue the connection.
DENY, which rejects the connection.
The optional elements are:
The elements in more detail:
Type: string
Must contain one of the following values:
ACCEPT: The authentication was successful, the client can continue the connection.
DENY: Reject the connection.
For example, the following sample code rejects the connection.
return { 'verdict': 'DENY' }
cookie
Type: dictionary |
Required: no |
Description: The cookie returned by the previous hook in the session. If this is the first call for that session, it is initialized as an empty dictionary, otherwise it has the value returned by one of the previous calls in this particular AA plugin. You can use the cookie to maintain the state for each particular connection or to transfer information between the different methods of the plugin. For an example that transfers information in the cookie between two methods, see Examples.
session_cookie
Type: dictionary |
Required: no |
Description: You can use the session cookie to maintain global state between plugins for each particular connection. If this is the first call for that session, it is initialized as an empty dictionary, otherwise it has the value returned by a previous plugin hook in the session.
additional_metadata
Type: string |
Required: no |
Description: The value of this string will be stored in the Additional metadata column of the SPS connection database, and will be available on the SPS search interface.
A session is the logical unit of user connections: it starts with logging in to the target, and ends when the connection ends. SPS executes the session_id hook when the session is closed. It is called exactly once for the same session.
TIP: You can use this hook 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.
You must implement the session_ended method in the plugin.
session_id
Type: string |
Description: The unique identifier of the session.
cookie
Type: dictionary |
Description: The cookie returned by the previous hook in the session. If this is the first call for that session, it is initialized as an empty dictionary, otherwise it has the value returned by one of the previous calls in this particular AA plugin. You can use the cookie to maintain the state for each particular connection or to transfer information between the different methods of the plugin. For an example that transfers information in the cookie between two methods, see Examples.
session_cookie
Type: dictionary |
Description: You can use the session cookie to maintain global state between plugins for each particular connection. If this is the first call for that session, it is initialized as an empty dictionary, otherwise it has the value returned by a previous plugin hook in the session.
This hook does not return values.
The following example formats every information received in the cookie into key-value pairs and prints a log message including this information into the log file.
def session_ended(self, session_id, session_cookie, cookie): session_details = ','.join(['{0}={1}'.format( key, cookie[key]) for key in sorted cookie.keys() ]) print("Session ended; session_id='{0}', session_details='{1}'". format(session_id, session_details))
The following example checks if the user has entered the string good as the token number. If the value of the token number is anything other than good, the plugin displays a prompt to the user up to three times. After three unsuccessful attempts, the plugin terminates the connection.
def authenticate(self, key_value_pairs, cookie): if key_value_pairs.get('token') == "good": return {'verdict': 'ACCEPT'} cookie['cnt'] = cookie.get('cnt', 0) + 1 if cookie['cnt'] > 3: return {'verdict': 'DENY'} return {'verdict': 'NEEDINFO', 'question': ('token', 'Enter token number: '), 'cookie': cookie }
The following example shows how to use the cookie to transfer data from the authenticate method to the session_ended method.
import sys class Plugin(object): def authenticate(self, session_id, cookie, protocol, connection_name, client_ip, client_port, key_value_pairs): token = key_value_pairs.pop('token', None) # Accept the connection if the user provides a token number if token: # Write code here that validates the token number and retrieves the username and usergroups of the user # We add the client_ip to the 'cookie' so it will be available in the session_ended method as well return { 'verdict': 'ACCEPT', 'gateway_user': 'username-received-from-third-party', 'gateway_groups': [ 'usergroup1-received-from-third-party', 'usergroup2-received-from-third-party'], 'additional_metadata': token, 'cookie': {'client_ip': client_ip} } # Display a prompt to the user to request a token number else: return { 'verdict': 'NEEDINFO', 'question': ('token', 'Enter your token number: ') } def session_ended(self, session_id, cookie): session_details = ','.join([ '{0}={1}'.format(key, cookie[key]) for key in sorted(cookie.keys()) ]) # Send a log message when the session ends, including the # client_ip address received in the cookie print("Session ended; session_id='{0}', session_details='{1}'". format(session_id, session_details))
© ALL RIGHTS RESERVED. Feedback Nutzungsbedingungen Datenschutz Cookie Preference Center