跳转到主要内容

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

所有提交的信息确保安全。

  • 关闭 [x]

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

所有提交的信息确保安全。

  • 关闭 [x]

软件开发环境下的邮件控制实践

梁悦, 软件工程师, IBM
梁悦的照片
梁悦,是在 IBM 中国软件开发中心工作的软件工程师,IBM Certified DB2 DBA,他目前正在从事企业级电子商务应用的开发。
魏 洪福, 高级软件工程师, IBM
魏洪福
魏洪福,来自 IBM 中国开发中心的高级软件工程师,目前从事 IBM Distributed Software 系统中 Notes 相关应用的开发。为银行、移动、电信、能源等行业客户和跨国公司提供 Lotus Domino/Notes 产品和解决方案的系统规划设计、顾问咨询、技术支持和培训服务,负责过多个大型项目的设计与实施。

简介: 本文将结合实例介绍软件开发环境下的邮件控制方法,包括自己编写程序实现和通过 Lotus Domino 邮件服务器配置两种方式,为读者提供有效的辅助和参考。

发布日期: 2011 年 12 月 14 日
级别: 初级
访问情况 : 6271 次浏览
评论: 


简介

邮件的发送和接收被应用于越来越多的商业应用场景,成为企业级应用程序所实现的工作流中不可或缺的一部分,邮件可能是一个工作流的开始,过程或者结束。在软件开发环境中,我们可能正在采取措施为阻止最终用户收到垃圾邮件而努力;我们可能想让产品环境和测试环境有不同的邮件使用者,让测试人员可以在测试环境测到尽可能多的情况;但是有的时候我们又想用最终用户的测试数据来做 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. 创建邮件组
图 1. 创建邮件组

打开 Domino 邮件服务器的配置文档,选择“路由器 /SMTP”, 选择“限制和控制”,选择“SMTP 外出控制”。在如下 2 处设置上述群组名称:


图 2. 配置设置
图 2. 配置设置

该群组中的用户发送邮件时,Domino 服务器将不为其发送,并返回给发送者类似的投递失败报告:


图 3. 投递失败报告
图 3. 投递失败报告

Domino 邮件服务器端有类似处理记录信息:


图 4. 服务器端处理记录
图 4. 服务器端处理记录

能够向 Internet 发送邮件的用户设置

  • 仅允许将来自以下 Internet 地址的消息发送到 Internet
  • 仅允许将来自以下 Notes 地址的消息发送到 Internet

用于设置白名单,适用于只允许部分用户发送邮件的情况。

在 domino 邮件服务器的公共通讯录中创建一个新的群组,例如群组名为“AllowSendMailGroup”,设置如下:


图 5. 创建邮件组
图 5. 创建邮件组

打开 Domino 邮件服务器的配置文档,选择“路由器 /SMTP”,选择“限制和控制”,选择“SMTP 外出控制”。在如下如下 2 处设置上述群组名称:


图 6. 配置 SMTP 外出控制
图 6. 配置 SMTP 外出控制

1) 用户 admin/notes 没有在上述允许发送邮件的群组中,因此 admin/notes 发送邮件时,服务器将不把邮件发送出去,并返回给发送者类似的投递失败报告:


图 7. 投递失败报告
图 7. 投递失败报告

Domino 邮件服务器端有类似处理记录信息:


图 8. 服务器端处理记录
图 8. 服务器端处理记录

2)而用户 lisi/notes 在上述允许发送邮件的群组中,因此可以成功发送邮件。下图是邮件成功到达 Domino 邮件服务器,等待发送:


图 9. 捕获邮件
图 9. 捕获邮件

Domino 服务器邮件规则来实现黑名单的功能

Domino 服务器可以创建基于邮件头或邮件正文内容的邮件过滤规则,来定义对特定邮件采取的操作(记录邮件、将邮件移动到数据库、拒绝接受、不邮递邮件(静删除、发送 NDR 不投递报告)、更改路由状态或停止处理)。测试邮件发送到 Domino 服务器上后,Domino 会据此设置自动执行指定的操作。

下面 3 个示例将给出不同的禁止发送邮件的处理方式:

“不邮递邮件(静删除)”规则

针对于测试环境,可以将不允许发送测试邮件的邮件地址添加到邮件规则中,选择“不邮递邮件(静删除)”操作。当 Domino 接收到以这些用户身份发送的邮件时,将直接删除掉。而不会给发件人发送任何报告。减少垃圾信息的往来。图示说明设置过程和处理效果:

打开 Domino 邮件服务器的配置文档,选择“路由器 /SMTP”, 选择“限制和控制”,选择“规则”。创建如下图所示的一条邮件规则 . 并启用该规则。


图 10. 邮件规则
图 10. 邮件规则

查看大图

根据设置,用户 admin/notes、admin@mailserver、lisi/notes、lisi@mailserver.com 发送邮件时,Domino 服务器将直接删除邮件,而不给出任何提示信息。

例如,用户 admin/notes 发送如下邮件,


图 11. 示例邮件
图 11. 示例邮件

Domino 邮件服务器直接删除邮件,在服务器端有类似处理记录信息:


图 12. 服务器端处理记录
图 12. 服务器端处理记录

“不接受消息”规则

针对于测试环境,可以将不允许发送测试邮件的邮件地址添加到邮件规则中,选择“不接受消息”操作。当用户身份发送的邮件时,将收到拒绝发送提示。图示说明设置过程和处理效果:

打开 Domino 邮件服务器的配置文档,选择“路由器 /SMTP”, 选择“限制和控制”,选择“规则”。创建如下图所示的一条邮件规则,并启用该规则。


图 13. 不接受消息规则
图 13. 不接受消息规则

根据设置,用户 admin/notes、admin@mailserver、lisi/notes、lisi@mailserver.com 发送邮件时,Domino 服务器将不接受这些邮件,并给出提示信息。

例如,用户 admin/notes 尝试发送邮件时,将收到类似提示,并无法发送出邮件:


图 14. 提示不接受邮件
图 14. 提示不接受邮件

“移入数据库”规则

针对于测试环境,可以将不允许发送测试邮件的邮件地址添加到邮件规则中,选择“移入数据库”操作。Domino 服务器接收到这些用户身份发送过来的邮件,将移入指定的数据库存储,而不发送给真正的收件人。开发人员可以到该数据库中进一步分析邮件内容。图示说明设置过程和处理效果:

打开 Domino 邮件服务器的配置文档,选择“路由器 /SMTP”, 选择“限制和控制”,选择“规则”。创建如下图所示的一条邮件规则 . 并启用该规则。


图 15. 移入数据库规则
图 15. 移入数据库规则

根据设置,用户 admin/notes、admin@mailserver、lisi/notes、lisi@mailserver.com 发送邮件时,Domino 服务器接收这些邮件后,直接存储到 mail\PendingMailBox.nsf 数据库,而不给发送者任何提示信息。

例如,用户 admin/notes 发送邮件后,Domino 服务器将其被转移到 mail\PendingMailBox.nsf 数据库,开发者可以到该数据库分析测试邮件。如图所示:


图 16. 邮件分析
图 16. 邮件分析

Domino 邮件服务器端有类似处理记录信息:


图 17. 服务器端处理记录
图 17. 服务器端处理记录

结束语

邮件控制几乎是每一个企业级应用开发者都会遇到的问题,它存在影响最终客户的可能性,所以需要慎重对待。读者可以根据本文所述针对具体情况做出适当的选择。


参考资料

学习

讨论

作者简介

梁悦的照片

梁悦,是在 IBM 中国软件开发中心工作的软件工程师,IBM Certified DB2 DBA,他目前正在从事企业级电子商务应用的开发。

魏洪福

魏洪福,来自 IBM 中国开发中心的高级软件工程师,目前从事 IBM Distributed Software 系统中 Notes 相关应用的开发。为银行、移动、电信、能源等行业客户和跨国公司提供 Lotus Domino/Notes 产品和解决方案的系统规划设计、顾问咨询、技术支持和培训服务,负责过多个大型项目的设计与实施。

关于报告滥用的帮助

报告滥用

谢谢! 此内容已经标识给管理员注意。


关于报告滥用的帮助

报告滥用

报告滥用提交失败。 请稍后重试。


developerWorks:登录


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 使用条款

 


当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

请选择您的昵称:

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

(长度在 3 至 31 个字符之间)


单击提交则表示您同意developerWorks 的条款和条件。 使用条款.

 


为本文评分

评论

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Lotus
ArticleID=781047
ArticleTitle=软件开发环境下的邮件控制实践
publish-date=12142011

标签

Help
使用 搜索 文本框在 My developerWorks 中查找包含该标签的所有内容。

使用 滑动条 调节标签的数量。

热门标签 显示了特定专区最受欢迎的标签(例如 Java technology,Linux,WebSphere)。

我的标签 显示了特定专区您标记的标签(例如 Java technology,Linux,WebSphere)。

使用搜索文本框在 My developerWorks 中查找包含该标签的所有内容。热门标签 显示了特定专区最受欢迎的标签(例如 Java technology,Linux,WebSphere)。我的标签 显示了特定专区您标记的标签(例如 Java technology,Linux,WebSphere)。