邮件的发送和接收被应用于越来越多的商业应用场景,成为企业级应用程序所实现的工作流中不可或缺的一部分,邮件可能是一个工作流的开始,过程或者结束。在软件开发环境中,我们可能正在采取措施为阻止最终用户收到垃圾邮件而努力;我们可能想让产品环境和测试环境有不同的邮件使用者,让测试人员可以在测试环境测到尽可能多的情况;但是有的时候我们又想用最终用户的测试数据来做 CAT(Customer Acceptance Testing, 用户验收测试),这个时候我们可能只关注具体业务逻辑而非邮件程序的测试,需要避免有邮件从测试环境发送到产品环境真实用户的电子信箱里,这会对他们的日常工作产生干扰,甚至会影响我们的客户满意度。为解决这些软件开发过程中遇到的与邮件接收有关的实际问题,我们使用了白名单和黑名单。
白名单的概念与黑名单相对应:白名单是设置能通过的用户,白名单以外的用户都不能通过;黑名单是设置不能通过的用户,黑名单以外的用户都能通过。这不是邮件控制的专利,凡是涉及到权限控制的领域几乎都应用了黑白名单规则,比如操作系统、防火墙、杀毒软件等等。
本文将通过应用程序实现和 IBM Lotus Domino 邮件服务器定制的两种方式来介绍黑白名单的配置和使用。
毫无疑问,程序员可以通过编程来完成自己对黑白名单的控制,这提供给我们更灵活的选择。比如不同的应用程序使用了相同的邮件服务器,同时这些应用程序因为不同的接收群体可能需要使用不同的黑白名单策略,那么一段隶属于不同应用程序的名单控制程序将是更加有效的方法。下面我们以一个 javax.mail 实现的白名单程序为例,清单 1. 列出了通过白名单的 XML 配置,它同时包含了标签定义以及测试数据。我们要做的是把这个白名单的列表一次加载到内存中,当然这也可以用数据库中的数据取代 XML 数据来表示白名单的配置,动态加载以避免应用重新发布来获得名单的改变。
清单 1. 白名单示例
<?xml version="1.0"?> <!DOCTYPE emails [ <!ELEMENT emails (email+)> <!ELEMENT email (#PCDATA)> <!ATTLIST email address CDATA ""> <!ATTLIST email description CDATA ""> <!ATTLIST email enable (true|false) "true"> ]> <!-- This is a whitelist prototype --> <emails> <email address="liangyue@cn.ibm.com" description="Yue Liang(Lion)" enable="true" /> <email address="weihongf@cn.ibm.com" description="Hong Fu Wei(Vick)" enable="false" /> </emails> |
余下的工作就是写一段 Java 程序去应用这个白名单。请参考清单 2 中的程序示例 , setupWhiteList() 方法用来将白名单加载到内存中 ; filterAddresses() 方法用来过滤邮件地址,如果输入的邮件地址不在白名单上,它将被程序从原有的邮件地址列表中过滤掉。sendOut() 方法就是最后的邮件发送实现,如果程序采用白名单过滤,将会扫描在邮件接受方,抄送方和暗送方中所有的邮件地址,讲不在白名单上的邮件地址全部过滤掉。
清单 2. 白名单实现例程
public void setupWhiteList() throws EmailException{
SAXBuilder sb=new SAXBuilder();
Document doc = null;
if(StringUtils.isEmpty(appCtx.getConfigParameter("mail.whitelist.config.file"))){
isUsingWhiteList = false;
return;
}
String configXMLFile = ... // filename
try {
doc = sb.build(configXMLFile);
Element root = doc.getRootElement();
List listEmailElement = root.getChildren();
listEnabledAddresses = new ArrayList();
for(int i=0;i<listEmailElement.size();i++){
Element elementEmail = (Element)listEmailElement.get(i);
if("true".equalsIgnoreCase(elementEmail.getAttributeValue("enable"))){
InternetAddress temp =
createInternetAddress(elementEmail.getAttributeValue("address"));
if(!listEnabledAddresses.contains(temp)){
listEnabledAddresses.add(temp);
}
}
}
} catch (Exception e){
//...Exception handler
}
}
public void filterAddresses(List list) throws EmailException{
if(isUsingWhiteList && listEnabledAddresses==null){
setupWhiteList();
}
for(int i=0;i<list.size();i++){
if(!listEnabledAddresses.contains(list.get(i))){
list.remove(i);
}
}
}
public void sendOut() throws EmailException {
Session mailSession = this.getMailsession();
MimeMessage message = new MimeMessage(mailSession);
try {
// Put parts in message
message.setSubject(this.subject, DEFAULT_CHARSET);
message.setFrom(this.fromAddress);
message.setContent(multipart);
if(mailEnabled) {
// normal mail send
} else {
if(isUsingWhiteList){
filterAddresses(toAddress);
filterAddresses(ccAddress);
filterAddresses(bccAddress);
if(!(toAddress.size()==0&&ccAddress.size()==0&&
bccAddress.size() ==0)){
message.addRecipients(Message.RecipientType.TO,
(Address[]) toAddress.toArray(new Address[0]));
message.addRecipients(Message.RecipientType.CC,
(Address[]) ccAddress.toArray(new Address[0]));
message.addRecipients(Message.RecipientType.BCC,
(Address[]) bccAddress.toArray(new Address[0]));
//Send the message
Transport.send(message);
}
}
}
} catch (Exception e){
//...Exception handler
}
}
|
Lotus Domino 作为企业级的协作平台,可以作为生产或测试环境的邮件服务器。可以将测试环境的邮件全部通过 SMTP 路由到 Domino 邮件服务器,由 Domino 服务器对邮件进行过滤和处理后再发送出去。Domino 提供了多种邮件过滤机制,可以根据实际情况进行选择。可以直接删除测试环境发出来的邮件,也可以暂存到一个集中的数据库供开发人员分析处理,可以允许授权的用户发送测试邮件等等。
在此介绍其中的两种实现方式:SMTP 外出控制和 服务器邮件规则。下述示例均使用最新版本的 Lotus Domino/Notes 8.5.2 进行说明。
Domino 服务器 SMTP 外出控制来实现黑白名单的功能
Domino 服务器可以设置“路由器 /SMTP 的外出控制”,用以限制用户发送 Internet 邮件。“外出发件人控制”可用于指定能够和不能向 Internet 发送邮件的用户。
不能够向 Internet 发送邮件的用户设置
- 拒绝将来自以下 Internet 地址的消息发送到 Internet
- 拒绝将来自以下 Notes 地址的消息发送到 Internet
用于设置黑名单,适用于只禁止部分用户发送邮件的情况。
在 domino 邮件服务器的公共通讯录中创建一个新的群组,例如群组名为“DenySendMailGroup”,设置如下:
图 1. 创建邮件组
打开 Domino 邮件服务器的配置文档,选择“路由器 /SMTP”, 选择“限制和控制”,选择“SMTP 外出控制”。在如下 2 处设置上述群组名称:
图 2. 配置设置
该群组中的用户发送邮件时,Domino 服务器将不为其发送,并返回给发送者类似的投递失败报告:
图 3. 投递失败报告
Domino 邮件服务器端有类似处理记录信息:
图 4. 服务器端处理记录
能够向 Internet 发送邮件的用户设置
- 仅允许将来自以下 Internet 地址的消息发送到 Internet
- 仅允许将来自以下 Notes 地址的消息发送到 Internet
用于设置白名单,适用于只允许部分用户发送邮件的情况。
在 domino 邮件服务器的公共通讯录中创建一个新的群组,例如群组名为“AllowSendMailGroup”,设置如下:
图 5. 创建邮件组
打开 Domino 邮件服务器的配置文档,选择“路由器 /SMTP”,选择“限制和控制”,选择“SMTP 外出控制”。在如下如下 2 处设置上述群组名称:
图 6. 配置 SMTP 外出控制
1) 用户 admin/notes 没有在上述允许发送邮件的群组中,因此 admin/notes 发送邮件时,服务器将不把邮件发送出去,并返回给发送者类似的投递失败报告:
图 7. 投递失败报告
Domino 邮件服务器端有类似处理记录信息:
图 8. 服务器端处理记录
2)而用户 lisi/notes 在上述允许发送邮件的群组中,因此可以成功发送邮件。下图是邮件成功到达 Domino 邮件服务器,等待发送:
图 9. 捕获邮件
Domino 服务器可以创建基于邮件头或邮件正文内容的邮件过滤规则,来定义对特定邮件采取的操作(记录邮件、将邮件移动到数据库、拒绝接受、不邮递邮件(静删除、发送 NDR 不投递报告)、更改路由状态或停止处理)。测试邮件发送到 Domino 服务器上后,Domino 会据此设置自动执行指定的操作。
下面 3 个示例将给出不同的禁止发送邮件的处理方式:
“不邮递邮件(静删除)”规则
针对于测试环境,可以将不允许发送测试邮件的邮件地址添加到邮件规则中,选择“不邮递邮件(静删除)”操作。当 Domino 接收到以这些用户身份发送的邮件时,将直接删除掉。而不会给发件人发送任何报告。减少垃圾信息的往来。图示说明设置过程和处理效果:
打开 Domino 邮件服务器的配置文档,选择“路由器 /SMTP”, 选择“限制和控制”,选择“规则”。创建如下图所示的一条邮件规则 . 并启用该规则。
图 10. 邮件规则
查看大图。
根据设置,用户 admin/notes、admin@mailserver、lisi/notes、lisi@mailserver.com 发送邮件时,Domino 服务器将直接删除邮件,而不给出任何提示信息。
例如,用户 admin/notes 发送如下邮件,
图 11. 示例邮件
Domino 邮件服务器直接删除邮件,在服务器端有类似处理记录信息:
图 12. 服务器端处理记录
“不接受消息”规则
针对于测试环境,可以将不允许发送测试邮件的邮件地址添加到邮件规则中,选择“不接受消息”操作。当用户身份发送的邮件时,将收到拒绝发送提示。图示说明设置过程和处理效果:
打开 Domino 邮件服务器的配置文档,选择“路由器 /SMTP”, 选择“限制和控制”,选择“规则”。创建如下图所示的一条邮件规则,并启用该规则。
图 13. 不接受消息规则
根据设置,用户 admin/notes、admin@mailserver、lisi/notes、lisi@mailserver.com 发送邮件时,Domino 服务器将不接受这些邮件,并给出提示信息。
例如,用户 admin/notes 尝试发送邮件时,将收到类似提示,并无法发送出邮件:
图 14. 提示不接受邮件
“移入数据库”规则
针对于测试环境,可以将不允许发送测试邮件的邮件地址添加到邮件规则中,选择“移入数据库”操作。Domino 服务器接收到这些用户身份发送过来的邮件,将移入指定的数据库存储,而不发送给真正的收件人。开发人员可以到该数据库中进一步分析邮件内容。图示说明设置过程和处理效果:
打开 Domino 邮件服务器的配置文档,选择“路由器 /SMTP”, 选择“限制和控制”,选择“规则”。创建如下图所示的一条邮件规则 . 并启用该规则。
图 15. 移入数据库规则
根据设置,用户 admin/notes、admin@mailserver、lisi/notes、lisi@mailserver.com 发送邮件时,Domino 服务器接收这些邮件后,直接存储到 mail\PendingMailBox.nsf 数据库,而不给发送者任何提示信息。
例如,用户 admin/notes 发送邮件后,Domino 服务器将其被转移到 mail\PendingMailBox.nsf 数据库,开发者可以到该数据库分析测试邮件。如图所示:
图 16. 邮件分析
Domino 邮件服务器端有类似处理记录信息:
图 17. 服务器端处理记录
邮件控制几乎是每一个企业级应用开发者都会遇到的问题,它存在影响最终客户的可能性,所以需要慎重对待。读者可以根据本文所述针对具体情况做出适当的选择。
学习
- 参考 IBM Lotus Domino Information Center。
- 参考 IBM Lotus Domino 文档。
- 访问 developerWorks Lotus 专区。
- 随时关注 developerWorks 技术活动和网络广播。
讨论
- 加入 developerWorks 中文社区,developerWorks 社区是一个面向全球 IT 专业人员,可以提供博客、书签、wiki、群组、联系、共享和协作等社区功能的专业社交网络社区。
- 加入 IBM 软件下载与技术交流群组,参与在线交流。

