2020 年 11 月 24 日

IT Skills 波林

Polin WEI – 資訊工作者的技術手札

利用 passay 來作密碼規則驗證與自動產生密碼

2 min read
忘憂谷

利用 passay 來作密碼規則驗證與自動產生密碼

 

密碼原則是常來驗證使用者輸入是否過於簡單,要自已寫一套當然可以,但若有已經寫好的,那麼直接拿來使用,這樣可以加速應用程式的開發,這是不是更好呢? passay 就是一套可以用來作密碼規則驗證與自動產生密碼的套件,建議您不妨可以直接拿來使用。

首先,先加入對 passay 的相依套件。

dependencies {
 compile("org.passay:passay:1.4.0") // 密碼規則驗證與產生
}

 

再來建立你想要的規則

/**
 * 密碼規則 
 * 1.8-6 個字元
 * 2. 至少一個英文大寫
 * 3. 至少一個英文小寫
 * 4. 至少一個數字
 * 5. 不可以與 username 相同
 * 6. 不可以有空白字元
 * @return
 */
public List<Rule> passwordRules() {
 List<Rule> pr = new ArrayList<Rule>();
 // length between 8 and 16 characters
 pr.add(new LengthRule(8, 16));
 // at least one upper-case character
 pr.add(new CharacterRule(EnglishCharacterData.UpperCase, 1));
 // at least one lower-case character
 pr.add(new CharacterRule(EnglishCharacterData.LowerCase, 1));
 // at least one digit character
 pr.add(new CharacterRule(EnglishCharacterData.Digit, 1));
 // password can not same as username
 pr.add(new UsernameRule());
 // no whitespace
 pr.add(new WhitespaceRule());
 
 return pr; 
}

 

用於自動產生密碼時,使用 instanceof 來取得符合 CharacterRule 的規則。

/**
* 依 passwordRules() 來產生8個字元的密碼
* @return
*/
public String generatePassword() {      
 PasswordGenerator passwordGenerator = new PasswordGenerator();
 List<CharacterRule> rs = new ArrayList<CharacterRule>();
 
 List<Rule> rules = this.passwordRules();
 for (Rule rule : rules) {
  if (rule instanceof CharacterRule) {
   CharacterRule cr = (CharacterRule) rule;
   rs.add(cr);
  }
 }
 return passwordGenerator.generatePassword(8,rs);
}

 

驗證密碼時,若想要產生多語系的訊息時,可以參考 Spring Boot 讀取自定多語系 properties 檔 來自定義錯誤訊息。

/**
 * 依  passwordRules() 的密碼規則來驗證
 * @param username
 * @param password
 * @param locale
 * @return
 * @throws FileNotFoundException
 * @throws IOException
 */
public Map passwordIsValid(String username, String password, Locale locale) throws FileNotFoundException, IOException {     
 ReloadableResourceBundleMessageSource ms = new ReloadableResourceBundleMessageSource();         
 ms.setBasename("classpath:PasswordMessages");
 ms.setDefaultEncoding("UTF-8");
 SpringMessageResolver smr = new SpringMessageResolver(ms, locale);
 
 PasswordValidator validator = new PasswordValidator(smr,this.passwordRules());
 
 PasswordData pd = new PasswordData(username, password);
 RuleResult result = validator.validate( pd );
 
 Map validResult = new LinkedHashMap<>();
 if(result.isValid()){
  validResult.put("isValid", true);
  validResult.put("message", validator.getMessages(result));
 } else {
  validResult.put("isValid", false);
  validResult.put("message", validator.getMessages(result));
 }
 return validResult;
}

 

最後,建立測試程式來試試看,這樣很快速吧。

@SpringBootTest
class AppsApplicationTests {
 private final Logger logger = LoggerFactory.getLogger(this.getClass());

 @Autowired 
 SystemService sysService;

 @Test
 void testPasswordRules() throws FileNotFoundException, IOException {
  Locale locale = Locale.TRADITIONAL_CHINESE;
  Map result = sysService.passwordIsValid("user","userpwd123" , locale);
  System.out.println(result.get("isValid"));
  System.out.println(result.get("message"));
 }
 
 @Test
 void testPasswordGenerate() {
  System.out.println(sysService.generatePassword());
 }

}

密碼驗證的輸出結果

false
[密碼必須包含 1 個或多個大寫字符。, 密碼包含為用戶 ID: user 。]

 

 

 

 

 

Copyright © All rights reserved. | Newsphere by AF themes.