最近项目中客户有对Backoffice用户的修改密码的复杂度的需求,本以为产品并未有原生支持,搜索过后才发现,Hybris已经为我们提供了一套比较完整的,非常容易扩展的对密码复杂度的支持模块,只是默认并未打开此配置。
实现
总体来说,Hybris对于密码复杂度的主要接口有PasswordPolicyService,PasswordPolicy以及PasswordPolicyService的默认实现DefaultPasswordPolicyService,PasswordPolicy的默认实现RegexPasswordPolicy、BlacklistFilePasswordPolicy,具体类图如下(引用自WIKI):
根据用户组配置不同的密码复杂度策略
Password Policy支持根据不同的用户组配置不同的密码复杂度策略,比如
password.policy.foo.groups.included=group1,group2
同时也支持通配符策略,如会匹配到所有的用户组,如使用匹配所有的用户组,还可以配置excluded属性来剔除不想使用该策略的用户组,例如:
# match all groups except excluded_group for foo policy
password.policy.foo.groups.included=*
password.policy.foo.groups.excluded=excluded_group
OOTB Password Policy实现:
OOTB提供了两种简单的密码策略,如下(来自WIKI)
使用
OOTB对于默认提供的两种密码策略的默认配置如下:
# UIDs of user groups for which policy will be applied
# * - can be used as a wildcard to match all groups
password.policy.regex.groups.included=regexPasswordPolicyGroup
password.policy.regex.groups.excluded=
password.policy.blacklist.groups.included=blacklistPasswordPolicyGroup
password.policy.blacklist.groups.excluded=
但是由于默认并没有用户组regexPasswordPolicyGroup、blacklistPasswordPolicyGroup所以OOTB的密码复杂度配置默认没有生效。假设想对employeegroup启用,local.properties配置如下:
password.policy.blacklist.groups.included=employeegroup
password.policy.regex.groups.included=employeegroup
重启服务,再次修改任意employeegroup下的账号密码,若复杂度不符合要求,系统则会提示如图:
源码实现
WIKI中提到:
SAP Hybris Platform automatically handles the password security policies for Hybris Management Console and Backoffice. If you want to enable this feature for customers, implement appropriate password policy handling in your storefront.
Hybris为Backoffice和HMC启动了Password Policy,对于Storefront的需求,需要定制化。
既然在Backoffice中默认实现,原本以为会在Backoffice提供的ObjectSaveFacade中有PasswordPolicyService的引用,经过阅读源码发现并非如此,PasswordPolicyService是在一个定制化的UI Panel中实现:
具体Java(反编译)代码如下:
如当前用户有写入权限,则对Render绑定一个新的Listener,此Listener会监听修改密码Text的变化,及时进行校验:
if (writable) {
EventListener passwordChangeListener = this.createPasswordChangeListener(user, passwordBox, confirmationBox, encryptionChooser, notMatchLabel, widgetInstanceManager);
passwordBox.addEventListener("onChange", passwordChangeListener);
confirmationBox.addEventListener("onChange", passwordChangeListener);
}
具体监听如下:
protected EventListener createPasswordChangeListener(UserModel user, Textbox passwordTextbox, Textbox passwordConfirmationTextbox, Combobox encryptionChooser, Label messageLabel, WidgetInstanceManager widgetInstanceManager) {
return (event) -> {
String password = passwordTextbox.getText();
if (password != null) {
if (password.equals(passwordConfirmationTextbox.getText())) {
messageLabel.setVisible(false);
Comboitem selectedItem = encryptionChooser.getSelectedItem();
if (selectedItem != null) {
String encryption = (String)selectedItem.getValue();
List passwordPolicyViolations = this.getPasswordPolicyService().verifyPassword(user, password, encryption);
this.renderPasswordPolicyViolations(messageLabel, passwordPolicyViolations);
if (passwordPolicyViolations.isEmpty()) {
this.userService.setPassword(user, password, encryption);
widgetInstanceManager.getModel().changed();
}
}
} else {
messageLabel.setValue(Labels.getLabel("hmc.passwordsdonotmatch"));
messageLabel.setVisible(true);
}
}
};
}
Spring配置如下:
此实现的逻辑非常简单,在实际项目中多数会需要我们扩展自己的密码复杂度策略,不难看出,Hybris给我们提供的这几个类的设计十分灵活,可以有多种方式在不影响OOTB代码的基础上灵活的扩展。具体如何扩展出自己的密码复杂度策略,我们在后面的文章中具体举例。
Enjoy hybris, enjoy coding..
参考资料:https://help.hybris.com/6.4.0/hcd/dfeec89a46c64774892b46936d65d530.html