Introduction
The ATG documentation has multiple references on LDAP integration but it was found to only affect authentication to dyn admin. This is a custom Integration which help us integrate ATG BCC with LDAP. We can use LDAP to authenticate BCC users and assign roles so that we can achieve controlled access of BCC using LDAP.
- No need to keep the LDAP admin username and password in ATG
- LDAP admin can assign or revoke roles for a User
- Create User and Roles in LDAP
- The Distinguished Name :- LDAP User : CN=Users,DC=test,DC=com
- The Distinguished Name : LDAP role :OU=roles,DC=test,DC=com
- Use sAMAccountName of LDAP user for login to BCC
- There should be one to one mapping between the ATG BCC roles ( Roles defined in DPI_ROLES table) and the roles in LDAP
- For example, epubAdmin role in ATG should have a corresponding role in LDAP account with sAMAccountName as epubAdmin
- LDAP authentication on BCC Login.
- Override the findUser() method of IntrenalProfileFormHandler
- Use the LDAPLoginManager java to authenticate and fetch the user details from LDAP
- If LDAP authentication is successful, the following actions will be performed:
- If a user with same login name exists in ATG then load that Profile from the repository. If not create a new profile in ATG repository.
- If there is any mismatch between ATG and LDAP Data, synchronize LDAP user properties and roles with ATG using the modifyInternalProfileforLdapData() method of the LDAPLoginManager.
- Avoid ATG password validation
- /atg/userprofiling/InternalProfileUserAuthority
- passwordHasher= /ads/LDAPNullPasswordHasher
- If the LDAP authentication fails, then show invalid user or password message
- For that return the findUser() of the IntrenalProfileFormHandler with null value so that the parent method will add FormException to show invalid user or password message
- Set the password property of the user repositoryitem in InternalProfileAdaptor repository as non required
- Set /atg/dynamo/servlet/pipeline/ExpiredPasswordServlet.enabled=false to disable OOTB Expired Password configuration
- Configurations
- Create /ads/LDAPNullPasswordHasher Component
- Create a class LDAPNullPasswordHasher extends NullPasswordHasher
- Override the checkPassword method return true;
- Create /ads/LDAPLoginManager
- LDAP domain Name
- domainName=developerscrapped.com
- Modify /atg/userprofiling/InternalProfileUserAuthority
- passwordHasher= /ads/LDAPNullPasswordHasher
- Modify /atg/userprofiling/InternalProfileFormHandler
- Override the atg.userprofiling.ProfileForm#findUser(String, String, Repository, DynamoHttpServletRequest, DynamoHttpServletResponse) method
- Java Source
------------------------------------------------------------------------------------------------------------1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79public class LDAPLoginManager extends GenericService { private static final String AT_SIGN = "@"; private UserDirectoryTools userDirectoryTools; private ProfileTools profileTools; private String domainName; public LDAPUserInfo authenticate(final String userName, final String password) { final LDAPUserInfo ldapUser = new LDAPUserInfo(); final StringBuilder securityPrincipal = new StringBuilder().append(userName) .append(LDAPLoginManager.AT_SIGN) .append(this.domainName); final LDAPJNDIEnvironment ldapEnv = new LDAPJNDIEnvironment(); ldapEnv.setProviderURL("ldap://localhost:389"); ldapEnv.setSecurityAuthentication("simple"); ldapEnv.setSecurityPrincipal(securityPrincipal.toString()); ldapEnv.setSecurityCredentials(password); final DirContext loginctx = new InitialDirContext(ldapEnv); NamingEnumeration<SearchResult> results = null; String distinguishedName = null; final SearchControls controls = new SearchControls(); controls.setSearchScope(SearchControls.SUBTREE_SCOPE); controls.setCountLimit(10); controls.setTimeLimit(60000); results = loginctx.search("CN=Users,DC=test,DC=com", MessageFormat.format("(&(objectClass=user)(sAMAccountName={0}))", userName), controls); if (results.hasMore()) { final SearchResult result = results.next(); final Attributes attrs = result.getAttributes(); ldapUser.addProperty("firstName", (String) attrs.get("givenName").get()); distinguishedName = (String) attrs.get("distinguishedName").get(); } results = loginctx.search("OU=roles,DC=test,DC=com", MessageFormat.format("(&(objectClass=group)(member={0}))", userName), controls); while (results.hasMore()) { final SearchResult result = results.next(); final Attributes attrs = result.getAttributes(); ldapUser.getLdapRoles().add((String) attrs.get("sAMAccountName").get()); } return ldapUser; } public void modifyInternalProfileforLdapData(final LDAPUserInfo ldapUserInfo, final RepositoryItem profileItem) throws RepositoryException { this.profileTools.updateProperties(ldapUserInfo.getLdapProperties(), profileItem); this.userDirectoryTools.removeAllRolesFromUser(profileItem.getRepositoryId()); this.userDirectoryTools.assignRolesToUser(ldapUserInfo.getLdapRoles(), profileItem.getRepositoryId()); } }
------------------------------------------------------------------------------------------------------------1 2 3 4 5 6 7 8 9 10 11 12 13public class LDAPUserInfo { private final Dictionary ldapProperties = new ArrayDictionary(); private final Set<String> ldapRoles = new HashSet<String>(15); public void addProperty(final String key, final String value) { this.ldapProperties.put(key, value); } public Dictionary getLdapProperties() { return this.ldapProperties; } public Set<String> getLdapRoles() { return this.ldapRoles; } }
------------------------------------------------------------------------------------------------------------1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27public class ExtendedInternalProfileFormHandler extends ProfileFormHandler { @Override protected RepositoryItem findUser(final String pLogin, final String pPassword, final Repository pProfileRepository, final DynamoHttpServletRequest pRequest, final DynamoHttpServletResponse pResponse) throws RepositoryException, ServletException, IOException { LDAPUserInfo ldapUser; try { ldapUser = this.ldapLoginManager.authenticate(pLogin, pPassword); } catch (final Exception e) { return null;// super class method will add form exceptions } RepositoryItem profileItem = profileTools.getItem(pLogin, null, this.getLoginProfileType()); if (profileItem == null) { profileItem = profileTools.createUser(pLogin); } this.ldapLoginManager.modifyInternalProfileforLdapData(ldapUser, profileItem); return super.findUser(pLogin, pPassword, pProfileRepository, pRequest, pResponse); } }
1 2 3 4 5 6 7 8 9 10public class ExtendedInternalProfileTools extends CommerceProfileTools { public MutableRepositoryItem createUser(final String userName) throws RepositoryException { final MutableRepositoryItem profileItem = this.getProfileRepository().createItem(this.getDefaultProfileType()); profileItem.setPropertyValue(this.getPropertyManager().getLoginPropertyName(), userName); this.getProfileRepository().addItem(profileItem); return profileItem; } }
No comments:
Post a Comment