You need to sign in to do that
Don't have an account?
Laurie Drew
JIT Provisioning
I am trying to set up JIT provisioning, I have SSO set up and functioning properly, the SAML Assertion I receive from the IDP contains the FederationID in the subject, so I have written the following code to search for a contact that has the FederationID in the subject populated in a custom field Campus_id__c, but when I attempt to log in with a test ID a new user account is not being created, can anyone assist? I really appreciate any help that can be provided.
My Code:
global class SSOUserHandler implements Auth.SamlJitHandler {
//JIT Handler Exception
private class JitException extends Exception {}
//Handle User
private void handleUser(boolean create, User u, Map < String, String > attributes,
String federationIdentifier, boolean isStandard) {
if (create && attributes.containsKey('User.FederationIdentifier')) {
u.FederationIdentifier = attributes.get('User.FederationIdentifier');
}
if (attributes.containsKey('User.ProfileId')) {
String profileId = attributes.get('User.ProfileId');
Profile p = [SELECT Id FROM Profile WHERE Id =: profileId];
u.ProfileId = p.Id;
}
Contact c = [Select ID, Email, FirstName, LastName from Contact where Campus_ID__c =:federationIdentifier];
if (attributes.containsKey('User.FirstName')) {
u.FirstName = attributes.get('User.FirstName');
} else if (create) {
u.FirstName = c.FirstName;
}
if (attributes.containsKey('LastName')) {
u.FirstName = attributes.get('LastName');
} else if (create) {
u.LastName = c.LastName;
}
if(attributes.containsKey('User.Email')) {
u.Email = attributes.get('User.Email');
} else if (create) {
u.Email = c.Email;
}
if (attributes.containsKey('UserName')) {
u.UserName = attributes.get('UserName');
} else if (create) {
u.UserName = c.Email;
}
if (attributes.containsKey('User.CommunityNickname')) {
u.CommunityNickname = attributes.get('User.CommunityNickname');
}
if (attributes.containsKey('User.IsActive')) {
String IsActiveVal = attributes.get('User.IsActive');
u.IsActive = '1'.equals(IsActiveVal) || Boolean.valueOf(IsActiveVal);
}
String uid = UserInfo.getUserId();
User currentUser = [SELECT LocaleSidKey, LanguageLocaleKey, TimeZoneSidKey, EmailEncodingKey FROM User WHERE Id =: uid];
if (attributes.containsKey('User.LocaleSidKey')) {
u.LocaleSidKey = attributes.get('User.LocaleSidKey');
} else if (create) {
u.LocaleSidKey = currentUser.LocaleSidKey;
}
if (attributes.containsKey('User.LanguageLocaleKey')) {
u.LanguageLocaleKey = attributes.get('User.LanguageLocaleKey');
} else if (create) {
u.LanguageLocaleKey = currentUser.LanguageLocaleKey;
}
if (attributes.containsKey('User.Alias')) {
u.Alias = attributes.get('User.Alias');
} else if (create) {
String alias = '';
if (u.FirstName == null) {
alias = u.LastName;
} else {
alias = u.FirstName.charAt(0) + u.LastName;
}
if (alias.length() > 5) {
alias = alias.substring(0, 5);
}
u.Alias = alias;
}
if (attributes.containsKey('User.TimeZoneSidKey')) {
u.TimeZoneSidKey = attributes.get('User.TimeZoneSidKey');
} else if (create) {
u.TimeZoneSidKey = currentUser.TimeZoneSidKey;
}
if (attributes.containsKey('User.EmailEncodingKey')) {
u.EmailEncodingKey = attributes.get('User.EmailEncodingKey');
} else if (create) {
u.EmailEncodingKey = currentUser.EmailEncodingKey;
}
if (!create) {
update(u);
} else {
Insert u;
}
}
//Handle JIT
private void handleJit(boolean create, User u, Id samlSsoProviderId, Id communityId, Id portalId,
String federationIdentifier, Map < String, String > attributes, String assertion) {
if (communityId != null || portalId != null) {
handleUser(create, u, attributes, federationIdentifier, false);
} else {
handleUser(create, u, attributes, federationIdentifier, true);
}
}
//For New User
global User createUser(Id samlSsoProviderId, Id communityId, Id portalId,
String federationIdentifier, Map < String, String > attributes, String assertion) {
User u = new User();
handleJit(true, u, samlSsoProviderId, communityId, portalId, federationIdentifier, attributes, assertion);
return u;
}
//For Existing User
global void updateUser(Id userId, Id samlSsoProviderId, Id communityId, Id portalId,
String federationIdentifier, Map < String, String > attributes, String assertion) {
User u = [SELECT Id, FirstName, ContactId FROM User WHERE Id =: userId];
handleJit(false, u, samlSsoProviderId, communityId, portalId, federationIdentifier, attributes, assertion);
}
}
My Code:
global class SSOUserHandler implements Auth.SamlJitHandler {
//JIT Handler Exception
private class JitException extends Exception {}
//Handle User
private void handleUser(boolean create, User u, Map < String, String > attributes,
String federationIdentifier, boolean isStandard) {
if (create && attributes.containsKey('User.FederationIdentifier')) {
u.FederationIdentifier = attributes.get('User.FederationIdentifier');
}
if (attributes.containsKey('User.ProfileId')) {
String profileId = attributes.get('User.ProfileId');
Profile p = [SELECT Id FROM Profile WHERE Id =: profileId];
u.ProfileId = p.Id;
}
Contact c = [Select ID, Email, FirstName, LastName from Contact where Campus_ID__c =:federationIdentifier];
if (attributes.containsKey('User.FirstName')) {
u.FirstName = attributes.get('User.FirstName');
} else if (create) {
u.FirstName = c.FirstName;
}
if (attributes.containsKey('LastName')) {
u.FirstName = attributes.get('LastName');
} else if (create) {
u.LastName = c.LastName;
}
if(attributes.containsKey('User.Email')) {
u.Email = attributes.get('User.Email');
} else if (create) {
u.Email = c.Email;
}
if (attributes.containsKey('UserName')) {
u.UserName = attributes.get('UserName');
} else if (create) {
u.UserName = c.Email;
}
if (attributes.containsKey('User.CommunityNickname')) {
u.CommunityNickname = attributes.get('User.CommunityNickname');
}
if (attributes.containsKey('User.IsActive')) {
String IsActiveVal = attributes.get('User.IsActive');
u.IsActive = '1'.equals(IsActiveVal) || Boolean.valueOf(IsActiveVal);
}
String uid = UserInfo.getUserId();
User currentUser = [SELECT LocaleSidKey, LanguageLocaleKey, TimeZoneSidKey, EmailEncodingKey FROM User WHERE Id =: uid];
if (attributes.containsKey('User.LocaleSidKey')) {
u.LocaleSidKey = attributes.get('User.LocaleSidKey');
} else if (create) {
u.LocaleSidKey = currentUser.LocaleSidKey;
}
if (attributes.containsKey('User.LanguageLocaleKey')) {
u.LanguageLocaleKey = attributes.get('User.LanguageLocaleKey');
} else if (create) {
u.LanguageLocaleKey = currentUser.LanguageLocaleKey;
}
if (attributes.containsKey('User.Alias')) {
u.Alias = attributes.get('User.Alias');
} else if (create) {
String alias = '';
if (u.FirstName == null) {
alias = u.LastName;
} else {
alias = u.FirstName.charAt(0) + u.LastName;
}
if (alias.length() > 5) {
alias = alias.substring(0, 5);
}
u.Alias = alias;
}
if (attributes.containsKey('User.TimeZoneSidKey')) {
u.TimeZoneSidKey = attributes.get('User.TimeZoneSidKey');
} else if (create) {
u.TimeZoneSidKey = currentUser.TimeZoneSidKey;
}
if (attributes.containsKey('User.EmailEncodingKey')) {
u.EmailEncodingKey = attributes.get('User.EmailEncodingKey');
} else if (create) {
u.EmailEncodingKey = currentUser.EmailEncodingKey;
}
if (!create) {
update(u);
} else {
Insert u;
}
}
//Handle JIT
private void handleJit(boolean create, User u, Id samlSsoProviderId, Id communityId, Id portalId,
String federationIdentifier, Map < String, String > attributes, String assertion) {
if (communityId != null || portalId != null) {
handleUser(create, u, attributes, federationIdentifier, false);
} else {
handleUser(create, u, attributes, federationIdentifier, true);
}
}
//For New User
global User createUser(Id samlSsoProviderId, Id communityId, Id portalId,
String federationIdentifier, Map < String, String > attributes, String assertion) {
User u = new User();
handleJit(true, u, samlSsoProviderId, communityId, portalId, federationIdentifier, attributes, assertion);
return u;
}
//For Existing User
global void updateUser(Id userId, Id samlSsoProviderId, Id communityId, Id portalId,
String federationIdentifier, Map < String, String > attributes, String assertion) {
User u = [SELECT Id, FirstName, ContactId FROM User WHERE Id =: userId];
handleJit(false, u, samlSsoProviderId, communityId, portalId, federationIdentifier, attributes, assertion);
}
}
Yes I was able to resolve our issue, here is my updated class:
global class SSOUserHandler implements Auth.SamlJitHandler {
public string result {get; set;}
public string debug {get; set;}
public list<string> emails = new list<string>{'llinnemeier@innovateteam.com'};
//JIT Handler Exception
private class JitException extends Exception {}
//Handle User
private void handleUser(boolean create, User u, Map < String, String > attributes,
String federationIdentifier, boolean isStandard) {
system.debug('manual class');
system.debug('federationIdentifier '+federationIdentifier);
system.debug('user fed id '+attributes.get('User.FederationIdentifier'));
if (create && attributes.containsKey('User.FederationIdentifier') && attributes.get('User.FederationIdentifier') != null) {
u.FederationIdentifier = attributes.get('User.FederationIdentifier');
federationIdentifier = attributes.get('User.FederationIdentifier');
}
else {
u.FederationIdentifier = federationIdentifier;
}
Profile p;
if (attributes.containsKey('User.ProfileId')) {
String profileId = attributes.get('User.ProfileId');
if(profileId != null && profileId != '') {
p = [SELECT Id FROM Profile WHERE Id =: profileId];
}
system.debug('profile1: '+p);
}
if(p == null) {
p = [SELECT Id FROM Profile WHERE Name =: 'Support Community Login User'];
}
system.debug('profile2: '+p);
u.ProfileId = p.Id;
List<Contact> cons = [Select ID, Email, FirstName, LastName from Contact where Campus_ID__c =:federationIdentifier];
Contact c;
if(cons != null && cons.size() > 0) {
c = cons[0];
}
if(c != null) {
u.ContactId = c.Id;
}
if (attributes.containsKey('User.FirstName')) {
u.FirstName = attributes.get('User.FirstName');
} else if (create && c != null) {
u.FirstName = c.FirstName;
}
if (attributes.containsKey('LastName')) {
u.FirstName = attributes.get('LastName');
} else if (create && c != null) {
u.LastName = c.LastName;
}
if(attributes.containsKey('User.Email')) {
u.Email = attributes.get('User.Email');
} else if (create && c != null) {
u.Email = c.Email+'.temp';
}
if (attributes.containsKey('UserName')) {
u.UserName = attributes.get('UserName');
} else if (create && c != null) {
u.UserName = c.Email;
}
if (attributes.containsKey('User.CommunityNickname')) {
u.CommunityNickname = attributes.get('User.CommunityNickname');
}
if (attributes.containsKey('User.IsActive')) {
String IsActiveVal = attributes.get('User.IsActive');
u.IsActive = '1'.equals(IsActiveVal) || Boolean.valueOf(IsActiveVal);
}
String uid = UserInfo.getUserId();
User currentUser = [SELECT LocaleSidKey, LanguageLocaleKey, TimeZoneSidKey, EmailEncodingKey FROM User WHERE Id =: uid];
if (attributes.containsKey('User.LocaleSidKey')) {
u.LocaleSidKey = attributes.get('User.LocaleSidKey');
} else if (create) {
u.LocaleSidKey = currentUser.LocaleSidKey;
}
if (attributes.containsKey('User.LanguageLocaleKey')) {
u.LanguageLocaleKey = attributes.get('User.LanguageLocaleKey');
} else if (create) {
u.LanguageLocaleKey = currentUser.LanguageLocaleKey;
}
if (attributes.containsKey('User.Alias')) {
u.Alias = attributes.get('User.Alias');
} else if (create) {
String alias = '';
if (u.FirstName == null) {
alias = u.LastName;
} else {
alias = u.FirstName.charAt(0) + u.LastName;
}
if (alias.length() > 5) {
alias = alias.substring(0, 5);
}
u.Alias = alias;
}
if (attributes.containsKey('User.TimeZoneSidKey')) {
u.TimeZoneSidKey = attributes.get('User.TimeZoneSidKey');
} else if (create) {
u.TimeZoneSidKey = currentUser.TimeZoneSidKey;
}
if (attributes.containsKey('User.EmailEncodingKey')) {
u.EmailEncodingKey = attributes.get('User.EmailEncodingKey');
} else if (create) {
u.EmailEncodingKey = currentUser.EmailEncodingKey;
}
try {
if (!create) {
//update(u); //GB 1/10/2019
}
else {
Insert u;
}
system.debug('success ' + u);
result = 'Success';
system.debug('result ' + result + ' ' + debug);
}
catch(Exception e) {
result = 'Failure';
debug += ' User record not inserted';
system.debug('result ' + result + ' ' + debug + ' ' + e);
Messaging.SingleEmailMessage email1 = new Messaging.SingleEmailMessage();
email1.setToAddresses(emails);
email1.setSubject('Error in JIT Provisioning failed to insert');
email1.setHtmlBody('Debug: <br/>' + debug + ' <br/> u.federationIdentifier: ' + federationIdentifier + e.getMessage());
Messaging.sendEmail(new Messaging.Email[]{email1});
}
}
//Handle JIT
private void handleJit(boolean create, User u, Id samlSsoProviderId, Id communityId, Id portalId,
String federationIdentifier, Map < String, String > attributes, String assertion) {
if (communityId != null || portalId != null) {
handleUser(create, u, attributes, federationIdentifier, false);
} else {
handleUser(create, u, attributes, federationIdentifier, true);
}
}
//For New Users
global User createUser(Id samlSsoProviderId, Id communityId, Id portalId,
String federationIdentifier, Map < String, String > attributes, String assertion) {
User u = new User();
handleJit(true, u, samlSsoProviderId, communityId, portalId, federationIdentifier, attributes, assertion);
return u;
}
//For Existing Users
global void updateUser(Id userId, Id samlSsoProviderId, Id communityId, Id portalId,
String federationIdentifier, Map < String, String > attributes, String assertion) {
User u = [SELECT Id, FirstName, ContactId FROM User WHERE Id =: userId];
handleJit(false, u, samlSsoProviderId, communityId, portalId, federationIdentifier, attributes, assertion);
}
}
All Answers
Were you ever able to find a solution regarding JIT, we are also experiancing the same problem. Any pointers would help.
Thanks,
Gary
Yes I was able to resolve our issue, here is my updated class:
global class SSOUserHandler implements Auth.SamlJitHandler {
public string result {get; set;}
public string debug {get; set;}
public list<string> emails = new list<string>{'llinnemeier@innovateteam.com'};
//JIT Handler Exception
private class JitException extends Exception {}
//Handle User
private void handleUser(boolean create, User u, Map < String, String > attributes,
String federationIdentifier, boolean isStandard) {
system.debug('manual class');
system.debug('federationIdentifier '+federationIdentifier);
system.debug('user fed id '+attributes.get('User.FederationIdentifier'));
if (create && attributes.containsKey('User.FederationIdentifier') && attributes.get('User.FederationIdentifier') != null) {
u.FederationIdentifier = attributes.get('User.FederationIdentifier');
federationIdentifier = attributes.get('User.FederationIdentifier');
}
else {
u.FederationIdentifier = federationIdentifier;
}
Profile p;
if (attributes.containsKey('User.ProfileId')) {
String profileId = attributes.get('User.ProfileId');
if(profileId != null && profileId != '') {
p = [SELECT Id FROM Profile WHERE Id =: profileId];
}
system.debug('profile1: '+p);
}
if(p == null) {
p = [SELECT Id FROM Profile WHERE Name =: 'Support Community Login User'];
}
system.debug('profile2: '+p);
u.ProfileId = p.Id;
List<Contact> cons = [Select ID, Email, FirstName, LastName from Contact where Campus_ID__c =:federationIdentifier];
Contact c;
if(cons != null && cons.size() > 0) {
c = cons[0];
}
if(c != null) {
u.ContactId = c.Id;
}
if (attributes.containsKey('User.FirstName')) {
u.FirstName = attributes.get('User.FirstName');
} else if (create && c != null) {
u.FirstName = c.FirstName;
}
if (attributes.containsKey('LastName')) {
u.FirstName = attributes.get('LastName');
} else if (create && c != null) {
u.LastName = c.LastName;
}
if(attributes.containsKey('User.Email')) {
u.Email = attributes.get('User.Email');
} else if (create && c != null) {
u.Email = c.Email+'.temp';
}
if (attributes.containsKey('UserName')) {
u.UserName = attributes.get('UserName');
} else if (create && c != null) {
u.UserName = c.Email;
}
if (attributes.containsKey('User.CommunityNickname')) {
u.CommunityNickname = attributes.get('User.CommunityNickname');
}
if (attributes.containsKey('User.IsActive')) {
String IsActiveVal = attributes.get('User.IsActive');
u.IsActive = '1'.equals(IsActiveVal) || Boolean.valueOf(IsActiveVal);
}
String uid = UserInfo.getUserId();
User currentUser = [SELECT LocaleSidKey, LanguageLocaleKey, TimeZoneSidKey, EmailEncodingKey FROM User WHERE Id =: uid];
if (attributes.containsKey('User.LocaleSidKey')) {
u.LocaleSidKey = attributes.get('User.LocaleSidKey');
} else if (create) {
u.LocaleSidKey = currentUser.LocaleSidKey;
}
if (attributes.containsKey('User.LanguageLocaleKey')) {
u.LanguageLocaleKey = attributes.get('User.LanguageLocaleKey');
} else if (create) {
u.LanguageLocaleKey = currentUser.LanguageLocaleKey;
}
if (attributes.containsKey('User.Alias')) {
u.Alias = attributes.get('User.Alias');
} else if (create) {
String alias = '';
if (u.FirstName == null) {
alias = u.LastName;
} else {
alias = u.FirstName.charAt(0) + u.LastName;
}
if (alias.length() > 5) {
alias = alias.substring(0, 5);
}
u.Alias = alias;
}
if (attributes.containsKey('User.TimeZoneSidKey')) {
u.TimeZoneSidKey = attributes.get('User.TimeZoneSidKey');
} else if (create) {
u.TimeZoneSidKey = currentUser.TimeZoneSidKey;
}
if (attributes.containsKey('User.EmailEncodingKey')) {
u.EmailEncodingKey = attributes.get('User.EmailEncodingKey');
} else if (create) {
u.EmailEncodingKey = currentUser.EmailEncodingKey;
}
try {
if (!create) {
//update(u); //GB 1/10/2019
}
else {
Insert u;
}
system.debug('success ' + u);
result = 'Success';
system.debug('result ' + result + ' ' + debug);
}
catch(Exception e) {
result = 'Failure';
debug += ' User record not inserted';
system.debug('result ' + result + ' ' + debug + ' ' + e);
Messaging.SingleEmailMessage email1 = new Messaging.SingleEmailMessage();
email1.setToAddresses(emails);
email1.setSubject('Error in JIT Provisioning failed to insert');
email1.setHtmlBody('Debug: <br/>' + debug + ' <br/> u.federationIdentifier: ' + federationIdentifier + e.getMessage());
Messaging.sendEmail(new Messaging.Email[]{email1});
}
}
//Handle JIT
private void handleJit(boolean create, User u, Id samlSsoProviderId, Id communityId, Id portalId,
String federationIdentifier, Map < String, String > attributes, String assertion) {
if (communityId != null || portalId != null) {
handleUser(create, u, attributes, federationIdentifier, false);
} else {
handleUser(create, u, attributes, federationIdentifier, true);
}
}
//For New Users
global User createUser(Id samlSsoProviderId, Id communityId, Id portalId,
String federationIdentifier, Map < String, String > attributes, String assertion) {
User u = new User();
handleJit(true, u, samlSsoProviderId, communityId, portalId, federationIdentifier, attributes, assertion);
return u;
}
//For Existing Users
global void updateUser(Id userId, Id samlSsoProviderId, Id communityId, Id portalId,
String federationIdentifier, Map < String, String > attributes, String assertion) {
User u = [SELECT Id, FirstName, ContactId FROM User WHERE Id =: userId];
handleJit(false, u, samlSsoProviderId, communityId, portalId, federationIdentifier, attributes, assertion);
}
}
Thanks a bunch, can you please share the related test class. This is the light in the dark for Adminis like me.
Regards,
Gary
https://trailhead.salesforce.com/content/learn/modules/unit-testing-on-the-lightning-platform