OAuth & Authentication Flows
📖 Concept
Understanding OAuth and authentication is critical for integration architecture. Salesforce supports multiple OAuth flows for different scenarios.
OAuth 2.0 Flows in Salesforce:
Web Server Flow (Authorization Code) — Most common for web apps
- User redirected to Salesforce login
- App receives authorization code
- App exchanges code for access token + refresh token
- Use for: Web applications with server-side logic
User-Agent Flow (Implicit) — For client-side apps
- Access token returned directly in URL fragment
- No refresh token
- Use for: Single-page apps, mobile apps (legacy)
JWT Bearer Token Flow — Server-to-server (no user interaction)
- App uses a private key to sign a JWT
- Salesforce validates and returns an access token
- Use for: Backend integrations, CI/CD, automated processes
Client Credentials Flow — Machine-to-machine
- App uses client ID + secret to get a token
- No user context — runs as an integration user
- Use for: System integrations, data sync
Device Flow — For devices with limited input
- Device displays a code, user authorizes on another device
- Use for: IoT devices, CLI tools
Refresh Token Flow — Renew expired access tokens
- Use refresh token to get a new access token
- Avoids re-authentication
Connected Apps: To use OAuth, you must create a Connected App in Salesforce that defines:
- Consumer Key (Client ID)
- Consumer Secret (Client Secret)
- Callback URL
- OAuth Scopes (api, refresh_token, web, etc.)
- IP restrictions and policies
Security best practices:
- Always use HTTPS
- Store tokens securely (never in client-side code)
- Use the minimum required OAuth scopes
- Implement token rotation and refresh
- Monitor Connected App usage in Setup
💻 Code Example
1// OAuth & Authentication Patterns23// 1. JWT Bearer Token Flow (Server-to-Server)4public class JwtAuthService {56 private static final String TOKEN_ENDPOINT = 'https://login.salesforce.com/services/oauth2/token';7 private static final String CONSUMER_KEY = 'your_connected_app_consumer_key';89 public static String getAccessToken() {10 // In production, use Named Credentials instead of manual JWT1112 // Build JWT claims13 Map<String, Object> claims = new Map<String, Object>{14 'iss' => CONSUMER_KEY,15 'sub' => 'integration@company.com',16 'aud' => 'https://login.salesforce.com',17 'exp' => String.valueOf(18 Datetime.now().addMinutes(5).getTime() / 100019 )20 };2122 // In real implementation, sign with certificate23 // String jwt = createSignedJwt(claims, certificate);2425 HttpRequest req = new HttpRequest();26 req.setEndpoint(TOKEN_ENDPOINT);27 req.setMethod('POST');28 req.setHeader('Content-Type', 'application/x-www-form-urlencoded');29 req.setBody(30 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' +31 '&assertion=' + EncodingUtil.urlEncode('jwt_token_here', 'UTF-8')32 );3334 HttpResponse res = new Http().send(req);35 Map<String, Object> response = (Map<String, Object>)36 JSON.deserializeUntyped(res.getBody());3738 return (String) response.get('access_token');39 }40}4142// 2. Making authenticated calls to another Salesforce org43public class CrossOrgService {4445 public static List<Map<String, Object>> queryExternalOrg(String soql) {46 // Use Named Credential for auth47 HttpRequest req = new HttpRequest();48 req.setEndpoint('callout:Other_Salesforce_Org/services/data/v59.0/query?q=' +49 EncodingUtil.urlEncode(soql, 'UTF-8'));50 req.setMethod('GET');51 req.setHeader('Accept', 'application/json');5253 HttpResponse res = new Http().send(req);5455 Map<String, Object> result = (Map<String, Object>)56 JSON.deserializeUntyped(res.getBody());5758 return (List<Map<String, Object>>)59 (List<Object>) result.get('records');60 }61}6263// 3. Custom REST API with proper authentication check64@RestResource(urlMapping='/api/v1/secure/*')65global with sharing class SecureRestApi {6667 @HttpGet68 global static ResponseWrapper getData() {69 // The @RestResource automatically validates OAuth tokens70 // No manual auth check needed — Salesforce handles it7172 // But you should check permissions73 if (!Schema.SObjectType.Account.isAccessible()) {74 RestContext.response.statusCode = 403;75 return new ResponseWrapper(false, 'Insufficient permissions');76 }7778 List<Account> accounts = [79 SELECT Id, Name, Industry FROM Account LIMIT 1080 ];8182 return new ResponseWrapper(true, accounts);83 }8485 global class ResponseWrapper {86 public Boolean success;87 public Object data;88 public String message;8990 public ResponseWrapper(Boolean success, Object data) {91 this.success = success;92 this.data = data;93 }9495 public ResponseWrapper(Boolean success, String message) {96 this.success = success;97 this.message = message;98 }99 }100}
🏋️ Practice Exercise
OAuth & Authentication Practice:
- Create a Connected App in your developer org and configure OAuth scopes
- Use Postman to authenticate via Web Server Flow and make API calls
- Set up a JWT Bearer Token flow for server-to-server integration
- Create a Named Credential that handles OAuth token refresh automatically
- Build a custom REST API and test authentication with different user profiles
- Implement a token management service that caches and refreshes access tokens
- Set up IP restrictions on a Connected App and test access from different IPs
- Create a Canvas app that uses signed request authentication
- Configure OAuth policies: token lifetime, refresh token rotation, admin pre-authorization
- Audit Connected App usage using Setup → Connected App OAuth Usage
⚠️ Common Mistakes
Storing access tokens in custom settings or fields — tokens should be managed by Named Credentials, not stored in data
Not implementing refresh token logic — access tokens expire. Without refresh logic, integrations break
Using the same Connected App for all environments — create separate Connected Apps for dev/sandbox/production
Granting too broad OAuth scopes — 'full' scope gives complete access. Use minimum required scopes (api, refresh_token)
Not monitoring Connected App usage — unauthorized access can go undetected without monitoring
💼 Interview Questions
🎤 Mock Interview
Mock interview is powered by AI for OAuth & Authentication Flows. Login to unlock this feature.