1. 问题描述
用户在登录数据决策系统时需要进行 用户身份验证 ,系统会对输入的用户名和密码进行验证,以确保系统安全。
登录验证信息(用户名和登录密码)存储在数据库(FineReport 内置数据库 FineDB 或者其他外接数据库)中,验证时用户输入的密码与数据库中密码相同则验证通过。
若数据库被破解,则登录验证信息暴露,对系统安全造成威胁。怎样避免此类情况,保证系统安全呢?
2. 解决方案
用户可以对 FineDB 中的登录信息进行加密。保证即使数据库被破解,也无法得到用户的真正登录信息。
同时,FineReport 在 导入用户 中提供「自定义密码加密」方式,可以对用户在登录页输入的登录信息进行加密。当加密后的登录信息与 FineDB 库中的登录信息一致时,验证通过。如下图所示:
加密简介:自定义密码加密,即自定义一个密码加密类。
加密方式在类中描述,并保存在%FR_Home%\webapps\webroot\WEB-INF\classes文件夹中。
数据决策系统会在用户自定义加密算法的基础上再进行 SHA256 二次加密,以保证密码安全。
适用场景:导入的服务器数据集中的密码列为明文时,可以使用自定义加密。
登录密码:导入的服务器数据集中密码列的明文。
加密接口:通过接口编写自定义密码加密类,对用户输入的“密码”或“用户名和密码”经过自定义加密规则进行加密。支持的接口如下:
1)只需要对密码进行加密得到密文:String encode(String originText);//入参是明文密码,对密码进行加密得到密文
2)对用户名和密码进行加密得到密文:String encode(String originUserName, String originPassword);//入参是用户名和明文密码,返回结果是密文字符
注1:其中 String encode(String originUserName, String originPassword);加密方式为 2019-01-18 新增的接口,包含接口1的功能,推荐使用此接口。
注2:自定义加密算法,必须继承 AbstractPasswordValidator 类。
3. 实现思路
3.1 加密验证逻辑
如果用户在登录页面输入明文密码后,能够成功登录数据决策系统。那么在这个过程中会进行四次加密和一次登录验证。
导入用户后发生:
1)第一次加密:导入用户后,系统会对服务器数据集中的明文进行自定义加密。
2)第二次加密:系统统一进行的 SHA256 加密,加密对象为第一次加密服务器数据集后得到的密文,得到的密文写入 FineDB 库。
用户登录时发生:
3)第三次加密:用户选取的自定义密码加密方式,加密对象为用户输入的明文密码。
4)第四次加密:系统统一进行的 SHA256 加密,加密对象为第三次加密后的密文。
5)登录验证:对比第四次加密后得到的密文与 FineDB 库中的密文,一致则验证通过。
如下图所示:
3.2 实现步骤
1)自定义一个密码加密类,用于加密用户在登录页面输入的明文密码 A。
准备编译环境
编写 Java 文件
编译 class 文件
2)创建服务器数据集,存储用户的登录信息,包括用户名、登录密码等。
3)导入用户信息至数据决策平台,用于系统登录验证。
用户来源为步骤 2 中准备的服务器数据集。
密码选择服务器数据集中的密码,为自定义加密后的密文。
设置加密方式为自定义加密,使用步骤 1 中准备的密码加密类。
4. 自定义密码加密示例
本文示例:编写 BASE64 密码加密类,对用户输入的“密码”经过自定义加密规则进行加密,然后进行登录验证,成功登录数据决策系统。
注:本文仅对 Base64 加密方式进行简单示例,对于其他常见的加密方式,本文在第五节提供自定义类文件,用户可以根据自己的需求下载使用。
4.1 准备编译环境
编译程序前,需先创建一个 Java 工程环境,并且需要一个 Java 编辑器,如 Eclipse 或 idea 。
在编辑器下打开工程,选择「Properties>Java Build Path>Libraries」,导入 FineReport 工程 JAR 包,详细操作可参考:编译Java程序
4.2 编写Java文件
在编译器中定义一个类,命名为 Base64PasswordValidator.java,扩展于 AbstractPasswordValidator。Java 代码如下:
package com.fr.decision.privilege.encrpt;;
import com.fr.base.Base64;
import com.fr.base.ServerConfig;
import com.fr.decision.privilege.encrpt.AbstractPasswordValidator;
import com.fr.log.FineLoggerFactory;
import java.io.UnsupportedEncodingException;
public class Base64PasswordValidator extends AbstractPasswordValidator {
public Base64PasswordValidator() {
}
public String encode(String originText) {
try {
return Base64.encode(originText.getBytes(ServerConfig.getInstance().getServerCharset()));
} catch (UnsupportedEncodingException var3) {
FineLoggerFactory.getLogger().debug(var3.getMessage());
return "";
}
}
}
4.3 编译class文件
点击下载并解压获得 class 文件:Base64PasswordValidator.zip
1)生成 class 文件
编译 Base64PasswordValidator.java,生成 Base64PasswordValidator.class 文件。
2)导入 class 文件
将编译后的 Base64PasswordValidator.class 文件保存到%FR_HOME%/webapps/webroot/WEB-INF/classes/com/fr/decision/privilege/encrpt文件夹下。
4.4 创建服务器数据集
用户在数据库中准备的密码会经过两次加密后写入 FineDB 库,用于登录校验。保证即使数据库被破解,也无法得到用户的真正登录信息。
4.4.1 数据准备
准备一张用户信息表,其中 password 数据列中的密码是明文。表结构如下图所示:
示例:若用户 a 在登录页面实际输入的明文密码为:123456,则 password 列中存放的密码为 123456
点击下载用户信息表:导入用户.xlsx
4.4.2 新增服务器数据集
请自行使用第三方数据库管理工具,将上表导入数据库,并建立系统与该数据库的 数据连接 。下文将以 FRDemo 数据库为例。
1)管理员登录数据决策系统,点击「管理系统>数据连接>服务器数据集」,创建「SQL数据集」。如下图所示:
2)设置数据集名称为「导入用户」,数据连接选择「FRDemo」,SQL 语句为:
select * from 导入用户
4.5 设置加密方式
注:若用户选择其他自定义密码加密方式,可在本节 4.5.2 中更改自定义加密类。本文在第五节提供了常用的自定义加密类文件,用户可按需选用。
在导入用户中可以选择自定义密码加密方式来提升系统的安全性。
4.5.1 导入用户
1)管理员登录数据决策系统,点击「管理系统>用户管理>所有用户」,点击「导入用户」,配置用户信息。如下图所示:
4.5.2 加密配置
1)用户来源选择为:4.4.2 中准备的服务器数据集「导入用户」
2)密码选择为:password
3)加密方式选择为:自定义密码加密,使用 4.3 节中准备的 Base64PasswordValidator.class 自定义加密类
如下图所示:
点击「确定」,导入用户成功。如下图所示:
4.6 效果预览
用户 a 登录数据决策系统:
服务器数据集中用户 a 的密码:123456 ,在登录页面输入明文密码:123456。
点击「登录」,成功登录数据决策系统。如下图所示:
5. 常用的自定义密码加密方式
本文提供了常用的自定义密码加密方式文件,用户可根据需求使用。点击下载文件后放到指定文件夹下,并更改 4.5.2 节中的自定义类,其余步骤参照第四节示例即可。
5.1 BASE64加密用户名和密码
FineReport 支持使用 BASE64 加密方式对用户输入的用户名和密码一起进行加密。
现提供编译后的 BASE64 加密类,点击下载文件:Base64UserPasswordValidator.zip
1)点击下载并解压获得 class 文件,将文件保存到%FR_HOME%/webapps/webroot/WEB-INF/classes/com/fr/decision/privilege文件夹下。
2)配置服务器数据集中 password 列为“密码”的明文,系统会对“用户名+密码”进行加密,最终入库 FineDB。
示例:用户 a 的密码是 123456,则服务器数据集中,password 列应该是 123456,系统对 a123456 加密。
5.2 SHA256加密密码
FineReport 支持使用 SHA256 加密方式对用户输入的密码进行加密。
现提供编译后的 SHA256 加密类,点击下载文件:SHA256PasswordValidator.zip
点击下载并解压获得 class 文件,将文件保存到%FR_HOME%/webapps/webroot/WEB-INF/classes/com/fr/decision/privilege/encrpt文件夹下。
5.3 SHA256加密用户名和密码
FineReport 支持使用 SHA256 加密方式对用户输入的用户名和密码一起进行加密。
现提供编译后的 SHA256 加密类,点击下载文件:CustomSHA256PasswordValidator.zip
1)点击下载并解压获得 class 文件,将文件保存到%FR_HOME%/webapps/webroot/WEB-INF/classes/com/fr/decision/privilege/encrpt文件夹下。
2)配置服务器数据集中 password 列为“密码”的明文,系统会对“用户名+密码”进行加密,最终入库 FineDB。
示例:用户 a 的密码是 123456,则服务器数据集中,password 列应该是 123456,系统对 a123456 加密。
5.4 MD5(32位小写)加密密码
FineReport 支持使用 MD5(32位小写)加密方式对用户输入的密码进行加密。
现提供编译后的 MD5(32位小写)加密类,点击下载文件:MD5CasePasswordValidator.zip
点击下载并解压获得 class 文件,将文件保存到%FR_HOME%/webapps/webroot/WEB-INF/classes/com/fr/decision/privilege文件夹下。
5.5 MD5(32位小写)加密用户名和密码
FineReport 支持使用 MD5(32位小写)加密方式对用户输入的用户名和密码一起进行加密。
现提供编译后的 MD5(32位小写)加密类,点击下载文件:MD5CaseUserPasswordValidator.zip
1)点击下载并解压获得 class 文件,将文件保存到%FR_HOME%/webapps/webroot/WEB-INF/classes/com/fr/decision/privilege文件夹下。
2)配置服务器数据集中 password 列为“密码”的明文,系统会对“用户名+密码”进行加密,最终入库 FineDB。
示例:用户 a 的密码是 123456,则服务器数据集中,password 列应该是 123456,系统对 a123456 加密。
5.6 MD5(32位大写)加密密码
FineReport 支持使用 MD5(32位大写)加密方式对用户输入的密码进行加密。
现提供编译后的 MD5(32位大写)加密类,点击下载文件:MD5UpperCasePasswordValidator.zip
点击下载并解压获得 class 文件,将文件保存到%FR_HOME%/webapps/webroot/WEB-INF/classes/com/fr/decision/privilege文件夹下。
5.7 MD5(32位大写)加密用户名和密码
FineReport 支持使用 MD5(32位大写)加密方式对用户输入的用户名和密码一起进行加密。
现提供编译后的 MD5(32位大写)加密类,点击下载文件:MD5UpperCaseUserPasswordValidator.zip
1)点击下载并解压获得 class 文件,将文件保存到%FR_HOME%/webapps/webroot/WEB-INF/classes/com/fr/decision/privilege文件夹下。
2)配置服务器数据集中 password 列为“密码”的明文,系统会对“用户名+密码”进行加密,最终入库 FineDB。
示例:用户 a 的密码是 123456,则服务器数据集中,password 列应该是 123456,系统对 a123456 加密。