Avi Load Balancer supports SDKs to use IdP credentials for it and a REST API login. The Python SDK needs a SAML authentication profile set up on the Controller to establish a connection and access resources.
Logging into the Avi Load Balancer CLI using IdP credentials is not yet supported.
SAML-based authentication using the Python SDK is supported for Okta and OneLogin.
The service provider (SP) never directly interacts with the identity provider. A browser or the Python SDK acts as the agent to carry out all redirections.
The service provider needs to know to which identity provider to redirect before it has any idea who the user is.
The service provider does not know who the user is until the SAML assertion comes back from the identity provider.
The process of SAML authentication is asynchronous. Whether the IdP will finish the entire flow is unknown to the service provider. As a result, the service provider does not keep records of the status of any generated authentication requests. When an IdP responds to the service provider, the response must contain all necessary information.
For more information, see SAML Authentication for Single Sign-On topic.
SAML Python SDK
Under the SDK, a file named saml_avi_api.py
contains the IdP class definition for each supported IdP. IdP-specific classes are inherited from the ApiSession
base class. An IdP-specific class definition has its own authentication method to be called to authenticate a given user. URL redirection and SAML assertion are handled in this class. This class returns the Controller session after successful authentication from the given IdP.
Example of Okta
In this collection of code snippets, the OktaSAMLApiSession
class is used to authenticate a user for Okta IdP, get the Controller session, and create the virtual service.
from avi.sdk.saml_avi_api import OktaSAMLApiSession
- Create Avi Load Balancer API Session
-
api = OktaSAMLApiSession("10.10.10.42", "okta_username", "okta_password")
OR
api = ApiSession.get_session("controller_ip", username="foo", password="foo", idp=OktaSAMLApiSession)
- Create VS Using Pool sample_pool
-
pool_obj = api.get_object_by_name('pool', 'sample_pool') pool_ref = api.get_obj_ref(pool_obj) services_obj = [{'port': 80, 'enable_ssl': False}] vs_obj = {'name': 'sample_vs', 'ip_address': {'addr': '11.11.11.42', 'type': 'V4'}, 'services': services_obj, 'pool_ref': pool_ref} resp = api.post('virtualservice', data=vs_obj)
- Print List of all Virtual Services
-
resp = api.get('virtualservice') for vs in resp.json()['results']: print vs['name']
- Delete a Virtual Service
-
resp = api.delete_by_name('virtualservice', 'sample_vs')
Example of OneLogin
In this collection of code snippets, the OneloginSAMLApiSession
class is used to authenticate a user for OneLogin IdP, get the Controller session, and create the virtual service.
from avi.sdk.saml_avi_api import OneloginSAMLApiSession
- Create Avi Load Balancer API Session
-
api = OneloginSAMLApiSession("10.10.10.42", "onelogin_username", "onelogin_password")
OR
api = ApiSession.get_session("10.10.10.42", "ws1_username", "ws1_password", idp_class=WS1loginSAMLApiSession)
- Create VS Using Pool sample_pool
-
pool_obj = api.get_object_by_name('pool', 'sample_pool') pool_ref = api.get_obj_ref(pool_obj) services_obj = [{'port': 80, 'enable_ssl': False}] vs_obj = {'name': 'sample_vs', 'ip_address': {'addr': '11.11.11.42', 'type': 'V4'}, 'services': services_obj, 'pool_ref': pool_ref} resp = api.post('virtualservice', data=vs_obj)
- Print List of all Virtual Services
-
resp = api.get('virtualservice') for vs in resp.json()['results']: print vs['name']
- Delete a Virtual Service
-
resp = api.delete_by_name('virtualservice', 'sample_vs')
Example of Workspace ONE Access
In this collection of code snippets, the WS1loginSAMLApiSession
class is used to authenticate a user for WS1 IdP, get the Controller session, and create the virtual service.
from avi.sdk.saml_avi_api import WS1loginSAMLApiSession
- Create Avi Load Balancer API Session
-
session = WS1loginSAMLApiSession("10.10.10.42", "ws1_username", "ws1_password")
OR
api = ApiSession.get_session("10.10.10.42", "ws1_username", "ws1_password", idp_class=WS1loginSAMLApiSession)
- Create Pool with One Server
-
pool_obj = {'name': 'sample_pool', 'servers': [{'ip': {'addr': '192.0.0.1', 'type': 'V4'}}]} pool_resp = session.post('pool', data=pool_obj) print(pool_resp.json())
- Create vsvip
-
vsvip_obj = {'name': 'sample_vsvip', 'vip': [{'vip_id': '1', 'ip_address': {'addr': '11.11.11.42', 'type': 'V4'}}]} vsvip_resp = session.post('vsvip', data=vsvip_obj) print(vsvip_resp.json())
- Create Virtual Service using sample_vsvip and sample_pool
-
pool_ref = '/api/pool?name={}'.format(pool_obj.get('name')) vsvip_ref = '/api/vsvip?name={}'.format(vsvip_obj.get('name')) services_obj = [{'port': 80, 'enable_ssl': False}] vs_obj = {'name': 'sample_vs', 'services': services_obj, 'vsvip_ref': vsvip_ref, 'pool_ref': pool_ref} resp = session.post('virtualservice', data=vs_obj)
- Print List of all Virtual Services
-
resp = session.get('virtualservice') for vs in resp.json()['results']: print vs['name']
- Delete a Virtual Service
-
resp = session.delete_by_name('virtualservice', 'sample_vs')