Authentication
Overview¶
Before you can make requests to the Salesforce API, you need to authenticate
In aiosalesforce authentication is a dependency you provide
to the Salesforce client.
The typical usage pattern looks like this
(using the SoapLogin authentication method as an example):
import asyncio
from aiosalesforce import Salesforce, SoapLogin
from httpx import AsyncClient
auth = SoapLogin(
username="username",
password="password",
security_token="security-token",
)
async def main():
async with AsyncClient() as client:
salesforce = Salesforce(
client=client,
base_url="https://your-instance.my.salesforce.com",
auth=auth,
)
if __name__ == "__main__":
asyncio.run(main())
Best Practice
Always declare your authentication instance as a global variable and reuse it across your application. You can have many clients using the same authentication instance. By doing so, you can avoid unnecessary re-authentication and reduce the number of requests to the Salesforce API.
Warning
Keep your credentials safe and never hardcode them in your application. Use third-party libraries to acquire credentials from environment variables, configuration files, or secret management services during runtime.
Built-in Authentication Methods¶
| Method | Connected App | Server-to-Server |
|---|---|---|
| SOAP Login | ||
| Client Credentials Flow | ||
| JWT Bearer Flow |
SOAP Login¶
Authenticate using username, password, and security token.
from aiosalesforce import SoapLogin
auth = SoapLogin(
username="username",
password="password",
security_token="security-token",
)
Where to find security token?
Security token can be obtained from the Salesforce UI by navigating to
Settings > Personal Information > Reset My Security Token, clicking the
Reset Security Token button, and then checking your email for the new token.
When you update security token make sure to update all applications
which are using the old token for this user.
Client Credentials Flow¶
Authenticate using a connected app for server-to-server integrations.
from aiosalesforce import ClientCredentials
auth = ClientCredentials(
client_id="client-id",
client_secret="client-secret",
)
How to create and configure a connected app?
First, you need to creat a connected app in Salesforce:
- Navigate to
Setup>Apps>App Managerand clickNew Connected App - Check
Enable OAuth Settings - Check
Enable for Device Flow - Check
Enable Client Credentials Flow - Select necessary scopes (generally, it's
Full access (full))
Next, you need to enable the Client Credentials Flow for the connected app:
- Navigate to
Setup>Apps>App Managerand find your connected app - Click
Manageand thenEdit Policies - Select
All users may self-authorizein thePermitted Userssection - Select a user on behalf of which the connected app will authenticate and
perform actions in the
Run Asfield of theClient Credentials Flowsection - (optional) Set the
Timeout Valuefield to whichever value is appropriate in your case - Click
Save
Finally, you need to retrieve the client_id and client_secret for the connected
app:
- Navigate to
Setup>Apps>App Managerand find your connected app - Click
Viewand then clickManage Consumer Details - Copy the
Consumer Key(client_id) andConsumer Secret(client_secret) values. If you need to reset your credentials, you do it here as well.
If you configured timeout for the access token when creating the connected app,
you can use the timeout parameter to specify duration in seconds after which
the access token will be automatically refreshed. This way you can save a retry API
call which would normally be retried due to 401 (token expired) by pre-emptively
refreshing the token.
auth = ClientCredentials(
client_id="client-id",
client_secret="client-secret",
timeout=900, # 15 minutes
)
JWT Bearer Flow¶
Authenticate using connected app and RSA private key.
from aiosalesforce import JwtBearerFlow
auth = JwtBearerFlow(
client_id="client-id",
username="username",
private_key="path/to/private-key.pem",
)
Where:
client_idis the connected app's consumer keyusernameis the username of the user on behalf of which the connected app will authenticate and perform actionsprivate_keyis the path to the RSA private key file (must be in PEM format)
You can optionally provide private_key_passphrase (if the private key is encrypted)
and timeout (if you set connected app timeout) parameters.
Warning
The JWT Bearer Flow requires PyJWT and cryptography libraries to be installed.
You can install them using pip install aiosalesforce[jwt].
How to configure a connected app to use JWT Bearer Flow?
Follow the same steps as for the Client Credentials Flow to create a connected app.
Create certificate and download certificate:
- Navitate to
Setup>Security>Certificate and Key Management - Click
Create Self-Signed Certificate, give it label, name, select key size, checkExportable Private Key, and clickSave - Navigate back to
Certificate and Key Managementand click onExport to Keystore(password needs to contain special characters, otherwise Salesforce will tell you that you don't have sufficient privileges). Password is needed only to subsequently extract the private key so you can discard it after you are done with the process. - Click
Exportand save it locally (e.g.certificate.crt)
Extract private key:
- Run the following command to extract the private key from the keystore: Enter password when prompted
- Run the following command to extract the private key from the PKCS12 file:
The
private-key.pemfile is your RSA private key
Connected app needs additional configuration to use JWT Bearer Flow:
- Navigate to
Setup>Apps>App Managerand find your connected app - Click
Manageand then clickEdit Policies - Under
Permitted Users, selectAdmin approved users are pre-authorized Save- Navigate to
Setup>Apps>App Manager, find your connected app, and clickEdit - Check
Use digital signaturesand upload the certificate (certificate.crt) you created and downloaded from Salesforce earlier Save
Update profile assigned to user(s) configured for this connected app:
- Navigate to
Setup>Users>Profiles - Find profile assigned to the user (or create a new one) and click
Edit - Enable
Connected App Accessfor the connected app you created
Custom Authentication¶
You can create a custom authentication class by subclassing the
Auth class.
You must implement the _acquire_new_access_token method which is responsible
for acquiring a new access token. This doesn't mean that you have to acquire a new
access token from Salesforce - only that calling this method should return a new
access token each time it is called. Examples of behavior:
- Fetch new token directly from Salesforce
- Fetch token from some service (e.g., centralized authentication service)
- Fetch token from cache and, if cache is empty/expired, fetch new token from Salesforce and update cache
You can optionally implement the _refresh_access_token method which is responsible
for refreshing the access token. If you don't implement this method, the
_acquire_new_access_token method will be called instead.
You can implement expiration mechanism by implementing the expired property in your
custom authentication class. This property should return a boolean value indicating
whether the access token has expired. Auth class will call the _refresh_access_token
method when the access token expires. By default the expired property always returns
False. You can declare whatever class attributes you need to implement the expiration
mechanism.
Information
When implementing custom authentication, you are responsible for emitting
RequestEvent
and
ResponseEvent
events using
client.event_bus.publish_event
method.
If you don't do this, any client-side logic built around events (e.g., logging or
metrics) will not receive request/response information related to authentication.
from aiosalesforce.auth import Auth
class MyAuth(Auth):
def __init__(
self,
# Your custom arguments
...
):
super().__init__()
# Your custom initialization logic
...
async def _acquire_new_access_token(self, client: Salesforce) -> str:
# Your custom logic to acquire new access token
...
async def _refresh_access_token(self, client: Salesforce) -> str:
# Your custom logic to refresh access token
...
@property
def expired(self) -> bool:
super().expired
# Your custom logic to check if access token has expired
...
Warning
You must follow these rules when making HTTP requests from your custom authentication class:
- Requets to Salesforce must be made using the
client.retry_policy.send_request_with_retriesmethod - Requests to other services must be made using the
client.httpx_clientattribute
Under no circumstances should you make HTTP
requests using the
client.request
method - this method calls authentication methods
and can lead to infinite recursion.
You can request any arguments in the __init__ method of your custom authentication
class. The __init__ method must call the super().__init__() method to initialize
the base class. After that, you can declare whatever attributes and methods you need.