Please Like this or comment below
Generate temporary passwords
During bulk loads or user on-boarding within Identity Manager, it many times may be necessary to generate a temporary password for the users / accounts. Within this publication, I try to illustrate a few methods with examples, whether it be via one of the following methods, there are various ways this can be accomplished.
- Policy Xpress Policy
- Javascript validation
- BLTH
Policy Xpress Policies (PXP) can be crafted to perform the below steps as well, but care should be taken to ensure the PXP fires during the UI Phase of the task, not post create. I would recommend this approach first, but care has to be taken with regards to prioritizing it and execution time (before the user is created).
PX policy for random password generation during User Creation -> PX Task -> Validation event.
This PX will generate random password in this format: ABcd12*# (Two capital letters, two small letters, two numbers and two special characters). You can update the composition as per requirement.
<?xml version="1.0" encoding="UTF-8"?> <ims:ImsTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://imsenvironmentobjects/xsd imsconfig://schema/ImsEnvironmentObjects.xsd" xmlns:ims="http://imsenvironmentobjects/xsd" xmlns:imsrule="http://imsmemberrule/xsd" xmlns:imsscope="http://imsscoperule/xsd" xmlns:imschange="http://imschangeaction/xsd"> <ManagedObject type="POLICY XPRESS EXPORT" friendlyName="PX101.10 Generate Default Password for User"> <Attribute name="friendlyName">PX101.10 Generate Default Password for User</Attribute> <Attribute name="enabled">true</Attribute> <Attribute name="category">PX - IDX Attribute Transformation</Attribute> <Attribute name="description">Policy Xpress policy for generation of default password for users</Attribute> <Attribute name="runOnce">false</Attribute> <Attribute name="priority">10</Attribute> <Attribute name="type">TASK</Attribute> <Attribute name="system">false</Attribute> <Attribute name="template">PolicyXpress</Attribute> <Attribute name="templateData"></Attribute> <Attribute name="whenToRun"><![CDATA[<Related> <WhenToRun> <Attribute name="type">TASK</Attribute> <Attribute name="step">VALIDATION</Attribute> <Attribute name="eventName">CreateInternalUser</Attribute> </WhenToRun> </Related>]]></Attribute> <Attribute name="dataElements"><![CDATA[<Related> <DataElement> <Attribute name="friendlyName">3of4_getRandomNumber2Digit</Attribute> <Attribute name="elementType">element.type.random.values</Attribute> <Attribute name="subElement">element.random.number</Attribute> <Attribute name="priority">13</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">2</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">getUpperRandomString1Char_1of2</Attribute> <Attribute name="elementType">element.type.string.parser</Attribute> <Attribute name="subElement">element.string.manipulation.substring</Attribute> <Attribute name="priority">7</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">{'upperAlphaList'}</PxParameter> <PxParameter extraInfo="" index="2" uiType="TYPED">{'getRandomNumber1Digit_1of2'}</PxParameter> <PxParameter extraInfo="" index="3" uiType="TYPED">{'getNextIndex_1of2'}</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">1of4_getUpperString2Chars</Attribute> <Attribute name="elementType">element.type.constant</Attribute> <Attribute name="subElement">element.constant.get</Attribute> <Attribute name="priority">9</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">{'getUpperRandomString1Char_1of2'}{'getUpperRandomString1Char_2of2'}</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">getLowerRandomString1Char_1of2</Attribute> <Attribute name="elementType">element.type.string.parser</Attribute> <Attribute name="subElement">element.string.manipulation.substring</Attribute> <Attribute name="priority">10</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">{'lowerAlphaList'}</PxParameter> <PxParameter extraInfo="" index="2" uiType="TYPED">{'getRandomNumber1Digit_1of2'}</PxParameter> <PxParameter extraInfo="" index="3" uiType="TYPED">{'getNextIndex_1of2'}</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">2of4_getLowerString2Chars</Attribute> <Attribute name="elementType">element.type.constant</Attribute> <Attribute name="subElement">element.constant.get</Attribute> <Attribute name="priority">12</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">{'getLowerRandomString1Char_1of2'}{'getLowerRandomString1Char_2of2'}</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">getRandomPassword8Chars</Attribute> <Attribute name="elementType">element.type.constant</Attribute> <Attribute name="subElement">element.constant.get</Attribute> <Attribute name="priority">17</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">{'1of4_getUpperString2Chars'}{'2of4_getLowerString2Chars'}{'3of4_getRandomNumber2Digit'}{'4of4_getRandomNonAlphaNum2Chars'}</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">nonAlphaNumList</Attribute> <Attribute name="elementType">element.type.constant</Attribute> <Attribute name="subElement">element.constant.get</Attribute> <Attribute name="priority">2</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">!@#$%-&*()</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">getRandomNumber1Digit_1of2</Attribute> <Attribute name="elementType">element.type.random.values</Attribute> <Attribute name="subElement">element.random.number</Attribute> <Attribute name="priority">3</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">1</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">getRandomNumber1Digit_2of2</Attribute> <Attribute name="elementType">element.type.random.values</Attribute> <Attribute name="subElement">element.random.number</Attribute> <Attribute name="priority">5</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">1</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">getRandomNonAlphaNum_1of2</Attribute> <Attribute name="elementType">element.type.string.parser</Attribute> <Attribute name="subElement">element.string.manipulation.substring</Attribute> <Attribute name="priority">14</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">{'nonAlphaNumList'}</PxParameter> <PxParameter extraInfo="" index="2" uiType="TYPED">{'getRandomNumber1Digit_1of2'}</PxParameter> <PxParameter extraInfo="" index="3" uiType="TYPED">{'getNextIndex_1of2'}</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">getNextIndex_1of2</Attribute> <Attribute name="elementType">element.type.math</Attribute> <Attribute name="subElement">element.math.increment</Attribute> <Attribute name="priority">4</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">{'getRandomNumber1Digit_1of2'}</PxParameter> <PxParameter extraInfo="" index="2" uiType="TYPED">1</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">getNextIndex_2of2</Attribute> <Attribute name="elementType">element.type.math</Attribute> <Attribute name="subElement">element.math.increment</Attribute> <Attribute name="priority">6</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">{'getRandomNumber1Digit_2of2'}</PxParameter> <PxParameter extraInfo="" index="2" uiType="TYPED">1</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">getRandomNonAlphaNum_2of2</Attribute> <Attribute name="elementType">element.type.string.parser</Attribute> <Attribute name="subElement">element.string.manipulation.substring</Attribute> <Attribute name="priority">15</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">{'nonAlphaNumList'}</PxParameter> <PxParameter extraInfo="" index="2" uiType="TYPED">{'getRandomNumber1Digit_2of2'}</PxParameter> <PxParameter extraInfo="" index="3" uiType="TYPED">{'getNextIndex_2of2'}</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">4of4_getRandomNonAlphaNum2Chars</Attribute> <Attribute name="elementType">element.type.constant</Attribute> <Attribute name="subElement">element.constant.get</Attribute> <Attribute name="priority">16</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">{'getRandomNonAlphaNum_1of2'}{'getRandomNonAlphaNum_2of2'}</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">upperAlphaList</Attribute> <Attribute name="elementType">element.type.constant</Attribute> <Attribute name="subElement">element.constant.get</Attribute> <Attribute name="priority">0</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">ABCDEFGHIJ</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">lowerAlphaList</Attribute> <Attribute name="elementType">element.type.constant</Attribute> <Attribute name="subElement">element.constant.get</Attribute> <Attribute name="priority">1</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">jihgfedcba</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">getUpperRandomString1Char_2of2</Attribute> <Attribute name="elementType">element.type.string.parser</Attribute> <Attribute name="subElement">element.string.manipulation.substring</Attribute> <Attribute name="priority">8</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">{'upperAlphaList'}</PxParameter> <PxParameter extraInfo="" index="2" uiType="TYPED">{'getRandomNumber1Digit_2of2'}</PxParameter> <PxParameter extraInfo="" index="3" uiType="TYPED">{'getNextIndex_2of2'}</PxParameter> </DataElement> <DataElement> <Attribute name="friendlyName">getLowerRandomString1Char_2of2</Attribute> <Attribute name="elementType">element.type.string.parser</Attribute> <Attribute name="subElement">element.string.manipulation.substring</Attribute> <Attribute name="priority">11</Attribute> <PxParameter extraInfo="" index="1" uiType="TYPED">{'lowerAlphaList'}</PxParameter> <PxParameter extraInfo="" index="2" uiType="TYPED">{'getRandomNumber1Digit_2of2'}</PxParameter> <PxParameter extraInfo="" index="3" uiType="TYPED">{'getNextIndex_2of2'}</PxParameter> </DataElement> </Related>]]></Attribute> <Attribute name="entryRules"><![CDATA[<Related/>]]></Attribute> <Attribute name="actionRules"><![CDATA[<Related> <ActionRule> <Attribute name="friendlyName">setPasswordAction</Attribute> <Attribute name="priority">10</Attribute> <Attribute name="description">Action to set password</Attribute> <Conditions/> <AddActions> <ActionElement> <Attribute name="friendlyName">setPasswordField</Attribute> <Attribute name="actionType">action.name.set.user.values</Attribute> <Attribute name="subAction">action.user.attribute.set</Attribute> <Attribute name="priority">0</Attribute> <PxParameter extraInfo="" index="1" uiType="SELECTED">%PASSWORD%</PxParameter> <PxParameter extraInfo="" index="2" uiType="TYPED">{'getRandomPassword8Chars'}</PxParameter> </ActionElement> <ActionElement> <Attribute name="friendlyName">setPasswordConfirm</Attribute> <Attribute name="actionType">action.name.set.user.values</Attribute> <Attribute name="subAction">action.user.attribute.set</Attribute> <Attribute name="priority">1</Attribute> <PxParameter extraInfo="" index="1" uiType="SELECTED">|passwordConfirm|</PxParameter> <PxParameter extraInfo="" index="2" uiType="TYPED">{'getRandomPassword8Chars'}</PxParameter> </ActionElement> </AddActions> <RemoveActions/> </ActionRule> </Related>]]></Attribute> </ManagedObject> </ims:ImsTemplate>
Before Policy Xpress existed in the product the following SDK methods were the only ones available. This technology still exists in the Identity Manager, so it's perfectly fine to use either of these methods. Also consider this is the way it has historically been done for over a decade, which in my mind makes it a viable alternative solution worth considering. The challenge in any of these solutions is that the password that's being generated needs to be compliant with the password policy setup within the Identity Manager, but there's no way to check the password while it's being created. Care needs to be taken to ensure the logical composition of the random password will always meet or exceed the password policy which is currently in use.
Javascript form field validation: The following example randomly generates a Password that contains an upper and lower case letter string combine with a random set of number and a client specified ! at the end. This could be easily extended and even incorporate regexes for pre-password policy checking.
This javascript method was setup to run on screen validation, but could be done just as easily on initialization.
// User Store & ISD Password Creation if (ScreenContext.getFieldValue("<Some_Attribute>").length() < 0) { ScreenContext.setFieldValue("Password", "<Some_Value>#" + ScreenContext.getFieldValue("<Some_Attribute>")); } else { var numberPrefix = new String(Math.floor(Math.random()*(9999-1000+1)+1000)); ScreenContext.setFieldValue("Password", "<Some_Value>#" + numberPrefix); } // AD Password Creation var adPassword = ""; var randomNumber = new String(Math.floor(Math.random()*(9999-1000+1)+1000)); var passwordPattern = new Vector(); var passwordGeneration = new Vector(); passwordPattern.add(1); passwordPattern.add(2); do { var conditionLower = false; var conditionUpper = false; for (var x = 0; x < 8; x++) { var selector = passwordPattern.get(Math.floor(Math.random()*passwordPattern.size())); passwordGeneration.add(selector); } if (passwordGeneration.contains(1)) { conditionLower = true; } else { conditionLower = false; passwordGeneration.clear(); } if (passwordGeneration.contains(2)) { conditionUpper = true; } else { conditionUpper = false; passwordGeneration.clear(); } } while (!conditionLower && !conditionUpper); for (var y = 0; y < passwordGeneration.size(); y++) { if (passwordGeneration.get(y) == 1) { adPassword = adPassword + "" + String.fromCharCode(97 + Math.round(Math.random() * 25)); } else if (passwordGeneration.get(y) == 2) { adPassword = adPassword + "" + String.fromCharCode(65 + Math.round(Math.random() * 25)); } } adPassword = adPassword + randomNumber + "!"; ScreenContext.setFieldValue("|ADPassword|", adPassword);
Business logic task handler (BLTH) password generation: And here's another example, this one is using a BLTH method to generate the password. You'll need to add the package name of your choice to the top before instantiating it in your IME.
import com.netegrity.imapi.BLTHAdapter; import com.netegrity.imapi.BLTHContext; import com.netegrity.ims.exception.IMSException; import com.netegrity.llsdk6.imsapi.managedobject.User; import java.util.Random; public class BLTHGeneratePassword extends BLTHAdapter { private static final String ALPHA_CAPS = "ABCDEFGHJKLMNPQRTWXY"; private static final String ALPHA = "abcdefghjkmnopqrstwxz"; private static final String NUM = "346789"; public void handleValidation(BLTHContext blthContext) throws Exception { int len = 8; int noOfCAPSAlpha = 2; int noOfDigits = 2; try { char[] str = new char[len]; str = generatePswd(len, noOfCAPSAlpha, noOfDigits); blthContext.getUser().setAttribute("password", str); } catch (NumberFormatException localNumberFormatException) { Object localObject = new IMSException(); ((IMSException)localObject).addUserMessage("Failed to set password" + localNumberFormatException); try { throw ((Throwable)localObject); } catch (Throwable e) { e.printStackTrace(); } } catch (Exception localException) { Object localObject = new IMSException(); ((IMSException)localObject).addUserMessage("Failed to set password" + localException); try { throw ((Throwable)localObject); } catch (Throwable e) { e.printStackTrace(); } } } public static char[] generatePswd(int len, int noOfCAPSAlpha, int noOfDigits) { Random rnd = new Random(); char[] pswd = new char[len]; int index = 0; for (int i = 0; i < noOfCAPSAlpha; i++) { index = getNextIndex(rnd, len, pswd); pswd[index] = "ABCDEFGHJKLMNPQRTWXY".charAt(rnd.nextInt("ABCDEFGHJKLMNPQRTWXY".length())); } for (int i = 0; i < noOfDigits; i++) { index = getNextIndex(rnd, len, pswd); pswd[index] = "346789".charAt(rnd.nextInt("346789".length())); } for (int i = 0; i < len; i++) { if (pswd[i] == 0) { pswd[i] = "abcdefghjkmnopqrstwxz".charAt(rnd.nextInt("abcdefghjkmnopqrstwxz".length())); } } return pswd; } private static int getNextIndex(Random rnd, int len, char[] pswd) { int index = rnd.nextInt(len); while (pswd[(index = rnd.nextInt(len))] != 0) {} return index; } }
Please respond with any questions or concerns.
Thank you.
Regards,
Chris Thomas
ca technologies
Principal Support Engineer
Identity Manager Reporting Expert
Tel: +1-631-342-4360
https://communities.ca.com/people/Chris_Thomas
https://www.linkedin.com/in/chrisryanthomas