OpenId Connect
How to use Google as OpenID Connect provider for Salesforce?
Topics
- Demo
- Auth. Provider Settings
- Open ID Provider client secret
- Auth.RegistrationHandler
- Auth.RegistrationHandler Log
- Using Metadata API
- Getting AccessToken for the Google using Auth.AuthToken and Getting userInfo
- References
Demo
Auth. Provider settings
Salesforce Configuration
URL | Link |
---|---|
Test-Only Initialization URL | https://mohansun-ea-02-dev-ed.my.salesforce.com/services/auth/test/Google |
Single Sign-On Initialization URL | https://mohansun-ea-02-dev-ed.my.salesforce.com/services/auth/sso/Google |
Existing User Linking URL | https://mohansun-ea-02-dev-ed.my.salesforce.com/services/auth/link/Google |
OAuth-Only Initialization URL | https://mohansun-ea-02-dev-ed.my.salesforce.com/services/auth/oauth/Google |
Callback URL | https://mohansun-ea-02-dev-ed.my.salesforce.com/services/authcallback/Google |
Single Logout URL | https://mohansun-ea-02-dev-ed.my.salesforce.com/services/auth/rp/oidc/logout |
Google OIDC Provider Configuration
URL | Link |
---|---|
Authorize Endpoint URL | https://accounts.google.com/o/oauth2/auth |
Token Endpoint URL | https://accounts.google.com/o/oauth2/token |
User Info Endpoint URL | https://www.googleapis.com/oauth2/v3/userinfo |
OID provider client secret details
- Note: Content is mangled here to protect the Identity
{
"web": {
"project_id": "oidtest-310720",
"client_id": "113225562349-fqktafcJUNK.apps.googleusercontent.com",
"client_secret": "6VIgVAz8NlJUNKIk4INu4",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"redirect_uris": [
"https://mohansun-ea-02-dev-ed.my.salesforce.com/services/authcallback/Google"
]
}
}
Sample Autocreated RegHandler class
// TODO:This autogenerated class includes the basics for a Registration
// Handler class. You will need to customize it to ensure it meets your needs and
// the data provided by the third party.
global class AutocreatedRegHandler1618428423355 implements Auth.RegistrationHandler {
global boolean canCreateUser(Auth.UserData data) {
//TODO: Check whether we want to allow creation of a user with this data
//Set<String> s = new Set<String>{'usernamea', 'usernameb', 'usernamec'};
//if(s.contains(data.username)) {
//return true;
//}
return false;
}
global User createUser(Id portalId, Auth.UserData data){
System.debug(data);
User u = [Select Id From User WHERE federationidentifier = :data.email LIMIT 1];
return u;
}
global void updateUser(Id userId, Id portalId, Auth.UserData data){
}
}
Querying AuthProvider
SELECT Id,authorizeUrl,
consumerKey,consumerSecret,
customMetadataTypeRecord,
defaultScopes,
DeveloperName,
errorUrl,
friendlyName,
iconUrl,
idTokenIssuer,
LinkKickoffUrl,
logoutUrl,
OauthKickoffUrl,
providerType,
tokenUrl,
userInfoUrl
FROM AuthProvider
Log from the RegHandler
Metadata details of this AuthProvider
$ sfdx mohanc:mdapi:list -u mohan.chinnappan.n_ea2@gmail.com -t AuthProvider
{
result: [
{
createdById: '0053h000002xQ5sAAE',
createdByName: 'Mohan Chinnappan',
createdDate: 2020-12-11T17:06:31.000Z,
fileName: 'authproviders/Google.authprovider',
fullName: 'Google',
id: '0SO3h000000CwxxGAC',
lastModifiedById: '0053h000002xQ5sAAE',
lastModifiedByName: 'Mohan Chinnappan',
lastModifiedDate: 1970-01-01T00:00:00.000Z,
type: 'AuthProvider'
}
]
}
$ sfdx mohanc:mdapi:retrieve -u mohan.chinnappan.n_ea2@gmail.com -t AuthProvider
{
"RetrieveRequest": {
"apiVersion": "51.0",
"unpackaged": [
{
"types": {
"members": "*",
"name": "AuthProvider"
}
}
]
}
}
{ result: { done: false, id: '09S3h000005hIRGEA2', state: 'Queued' } }
$ sfdx mohanc:mdapi:checkRetrieveStatus -u mohan.chinnappan.n_ea2@gmail.com -i 09S3h000005hIRGEA2
[
{
createdById: '',
createdByName: '',
createdDate: 2020-12-11T17:06:31.000Z,
fileName: 'unpackaged/authproviders/Google.authprovider',
fullName: 'Google',
id: '0SO3h000000CwxxGAC',
lastModifiedById: '',
lastModifiedByName: '',
lastModifiedDate: 1970-01-01T00:00:00.000Z,
type: 'AuthProvider'
},
{
createdById: '0053h000002xQ5sAAE',
createdByName: 'Mohan Chinnappan',
createdDate: 2021-04-16T01:12:48.036Z,
fileName: 'unpackaged/package.xml',
fullName: 'unpackaged/package.xml',
id: '',
lastModifiedById: '0053h000002xQ5sAAE',
lastModifiedByName: 'Mohan Chinnappan',
lastModifiedDate: 2021-04-16T01:12:48.036Z,
manageableState: 'unmanaged',
type: 'Package'
}
]
=== Writing zipFile base64 content to 09S3h000005hIRGEA2.zip.txt ...
=== Writing zipFile binary content to 09S3h000005hIRGEA2.zip ...
$ jar tvf 09S3h000005hIRGEA2.zip
1054 Fri Apr 16 01:12:48 EDT 2021 unpackaged/authproviders/Google.authprovider
224 Fri Apr 16 01:12:48 EDT 2021 unpackaged/package.xml
$ unzip 09S3h000005hIRGEA2.zip
Archive: 09S3h000005hIRGEA2.zip
inflating: unpackaged/authproviders/Google.authprovider
inflating: unpackaged/package.xml
$ cat authproviders/Google.authprovider
<?xml version="1.0" encoding="UTF-8"?>
<AuthProvider xmlns="http://soap.sforce.com/2006/04/metadata">
<authorizeUrl>https://accounts.google.com/o/oauth2/auth</authorizeUrl>
<consumerKey>_junk_-fqktafcmesni74spapbj1ep0pvja4oor.apps.googleusercontent.com</consumerKey>
<consumerSecret>_____</consumerSecret>
<defaultScopes>email openid profile</defaultScopes>
<executionUser>mohan.chinnappan@email.com</executionUser>
<friendlyName>Google</friendlyName>
<includeOrgIdInIdentifier>false</includeOrgIdInIdentifier>
<providerType>Google</providerType>
<registrationHandler>AutocreatedRegHandler1618428423355</registrationHandler>
<sendAccessTokenInHeader>false</sendAccessTokenInHeader>
<sendClientCredentialsInHeader>false</sendClientCredentialsInHeader>
<sendSecretInApis>true</sendSecretInApis>
<tokenUrl>https://accounts.google.com/o/oauth2/token</tokenUrl>
<userInfoUrl>https://www.googleapis.com/oauth2/v3/userinfo</userInfoUrl>
</AuthProvider>
Test-Only Initialization URL
- https://mohansun-ea-02-dev-ed.my.salesforce.com/services/auth/test/Google
- Run Test Only
Getting AccessToken for the Google using Auth.AuthToken and UserInfo
// file: ~/.apex/oidc.cls
String authProviderId = '0SO3h000000Cwxx';
String providerName = 'Google';
String accessToken = Auth.AuthToken.getAccessToken(authProviderId, providerName);
System.debug('accessToken: ' + accessToken);
# you can also use developer console to execute above apex code instead of CLI
sfdx mohanc:tooling:execute -a ~/.apex/oidc.cls -u mohan.chinnappan.n_ea2@gmail.com
apexCode: String authProviderId = '0SO3h000000Cwxx';
String providerName = 'Google';
String accessToken = Auth.AuthToken.getAccessToken(authProviderId, providerName);
System.debug('accessToken: ' + accessToken);
compiled?: true
executed?: true
{
line: -1,
column: -1,
compiled: true,
success: true,
compileProblem: null,
exceptionStackTrace: null,
exceptionMessage: null
}
Check logs
sfdx force:apex:log:list -u mohan.chinnappan.n_ea2@gmail.com
APPLICATION DURATION (MS) ID LOCATION SIZE (B) LOG USER OPERATION REQUEST START TIME STATUS
─────────── ───────────── ────────────────── ────────── ──────── ──────────────── ───────────────────────────────────────────────────────── ─────────── ──────────────────────── ───────
Unknown 94 07L3h00000AvxqyEAB SystemLog 3640 Mohan Chinnappan /services/data/v57.0/tooling/executeAnonymous Api 2023-04-04T05:44:30+0000 Success
sfdx force:apex:log:get -i 07L3h00000AvxqyEAB -u mohan.chinnappan.n_ea2@gmail.com | grep -i Debug
57.0 APEX_CODE,FINEST;APEX_PROFILING,INFO;CALLOUT,INFO;DB,INFO;NBA,INFO;SYSTEM,DEBUG;VALIDATION,INFO;VISUALFORCE,FINER;WAVE,INFO;WORKFLOW,INFO
Execute Anonymous: System.debug('accessToken: ' + accessToken);
22:44:30.1 (7497609)|USER_DEBUG|[4]|DEBUG|accessToken: ya29.a0Ael9sCNXJZqO7O34pvUcb4sDkO9S0X3hbBTxtMnnZ1H00TJQq_mhaPAR5fXffydfasdfsarerrvSneMUdC8Wen9YOHYNn4rQ1sNtiHDFQqRQ6gtqGPBdrgHFz3kBsTEobU4OP59OJSIJJ1OO1kUkaCgYKAUYSARMSFQF4udJh3LjnChU-94GnI--qgC6QcA0166
If you have used Developer Console to execute the apex code, here is the view from the Developer Console:
Let us get the userInfo
# Note the accessToken used here is mangled to protect identity
curl https://www.googleapis.com/oauth2/v3/userinfo -H "Authorization: Bearer ya29.a0Ael9sCNXJZqO7O34pvUcb4sDkO9S0X3hbBTxtMnnZ1H00TJQq_mhadfdj3335fXffy4JsugBpVZSjY06npxOmlFJPvSneMUdC8Wen9YOHYNn4rQ1sNtiHDFQqRQ6gtqGPBdrgHFz3kBsTEobU4OP59OJSIJJ1OO1kUkaCgYKAUYSARMSFQF4udJh3LjnChU-94GnI--qgC6QcA0166" -X GET
{
"sub": "102467670031694452102",
"name": "Mohan Chinnappan",
"given_name": "Mohan",
"family_name": "Chinnappan",
"picture": "https://lh3.googleusercontent.com/a/AGNmyxbp471dpjPtNSeeeejyyNbh1fFJqlknZUaDqrmb\u003ds96-c",
"email": "mohan.chinnappan.n@gmail.com",
"email_verified": true,
"locale": "en"
}
Viewing RegistrationHandlerUserUpdate log
sfdx force:apex:log:list -u mohan.chinnappan.n_ea2@gmail.com
APPLICATION DURATION (MS) ID LOCATION SIZE (B) LOG USER OPERATION REQUEST START TIME STATUS
─────────── ───────────── ────────────────── ────────── ──────── ──────────────── ───────────────────────────────────────────────────────── ─────────── ──────────────────────── ───────
Unknown 91 07L3h00000AvxrhEAB SystemLog 6559 Mohan Chinnappan RegistrationHandlerUserUpdate Application 2023-04-04T10:44:35+0000 Success
sfdx force:apex:log:get -i 07L3h00000AvxrhEAB -u mohan.chinnappan.n_ea2@gmail.com | grep -i Debug
03:44:35.5 (12059570)|USER_DEBUG|[25]|DEBUG|UserData:[attributeMap={email=mohan.chinnappan.n@gmail.com, email_verified=true, family_name=Chinnappan, given_name=Mohan, locale=en, name=Mohan Chinnappan, picture=https://lh3.googleusercontent.com/a/AGNmyxbp471dpjPtNSeeeejyyNbh1fFJqlknZUaDqrmb=s96-c, sub=102467670031694452102}, email=mohan.chinnappan.n@gmail.com, firstName=Mohan, fullName=Mohan Chinnappan, identifier=102467670031694452102, lastName=Chinnappan, link=null, locale=en, provider=Google, siteLoginUrl=null, username=null]
Resources
-
Okta specific
-
Videos
-
Playgrounds
About OpenID connect
- Simple Identity layer on top of the OAuth 2.0 protocol
- Allows Clients (like service providers) to verify the identity of the End-User based on the authentication performed by an Authorization Server
