【问题标题】:Office365 message encryption strips out email attachments when sending with Python使用 Python 发送时,Office365 消息加密会去除电子邮件附件
【发布时间】:2018-10-26 21:42:38
【问题描述】:

我有一个 python3 def,它通过 office 365 帐户发送 html 消息。我们要求使用 Office365 消息加密 (OME) 发送消息。这为用户提供了一个 html 附件,使他们在在线查看电子邮件之前通过 office 365 登录。我们已为将要发送邮件的电子邮件帐户上发送的所有邮件启用 OME。以下是一些观察:

  1. 通过启用 OME 的帐户通过 python def 发送时,查看加密邮件时没有附件。
  2. 通过普通帐户通过 python def 发送时,附件按预期显示在电子邮件中
  3. 使用 office365 网站或 Outlook 通过启用 OME 的帐户手动发送电子邮件时,附件会按预期显示在电子邮件中
  4. 电子邮件代码包括附加的 HTML 图像,在普通邮件和加密邮件中均能正常显示。

我敢打赌我错过了一些随机标题或其他东西 - 有人知道发生了什么吗?这是python代码:

def sendHTMLEmail(
    emaillist,
    subject,
    body,
    altBody,
    logger,
    mailuser,
    mailpassword,
    fileAttachments=None,
    embeddedImages=None
):  
    """
    Send an html-enabled email to a number of recipients. This method includes the options of embedding images in the email,
    attaching files to the email, and providing alternative plain text in case of an error rendering the HTML. 

    # Arguments
        emaillist (list[string]): List of email addresses to send to
        subject (string): Subject line of the email
        body (string): Body of the email. This can be plain text or HTML, depending on the email. 
        altBody (string): Alternate body text of the email. This will be displayed if the HTML cannot be rendered.
        logger (JvpyLog): optional logger override parameter 
        mailuser (string): SMTP username to send the mail as
        mailpassword (string): login password of the SMTP user
        fileAttachments (list[string]): list of fully qualified filenames to attach to the email
        embeddedImages (list[dict]): list of embeddedImage dicts specifying images to be embedded in the HTML boddy of the email

    # Special Types
    ###### embeddedImages [dict]:
    ```python
    {
        filename (string): fully qualified filename of the image
        imageid (string): unique id for the image. This will be refrernced in the HTML body of the email and repaced by the actual image. 
    }
    ```
    """
    logger.info("Sending email to the following recipients: " + str(emaillist))

    # Define these once; use them twice!
    strFrom = mailuser
    strTo = ", ".join(emaillist)

    # Create the root message and fill in the from, to, and subject headers
    msgRoot = MIMEMultipart('related')
    msgRoot['Subject'] = subject
    msgRoot['From'] = strFrom
    msgRoot['To'] = strTo
    msgRoot.preamble = 'This is a multi-part message in MIME format.'

    # Encapsulate the plain and HTML versions of the message body in an
    # 'alternative' part, so message agents can decide which they want to display.
    msgAlternative = MIMEMultipart('alternative')
    msgRoot.attach(msgAlternative)

    msgText = MIMEText(altBody)
    msgAlternative.attach(msgText)

    # We reference the image in the IMG SRC attribute by the ID we give it below
    msgText = MIMEText(body, 'html')
    msgAlternative.attach(msgText)

    # embed images if populated
    if embeddedImages is not None:
        for image in embeddedImages:
            logger.info("Embedding Image: " + str(image['filename']) + " as content id: " + str(image['imageid']))
            fp = open(image['filename'], 'rb')
            msgImage = MIMEImage(fp.read())
            fp.close()

            # Define the image's ID as referenced above
            msgImage.add_header('Content-ID', image['imageid'])
            msgRoot.attach(msgImage)

    # add attachements if populated
    if fileAttachments is not None:
        for filename in fileAttachments:
            logger.info("Attaching File: " + str(filename))
            part = MIMEApplication(
                open(filename,"rb").read(),
                Name=os.path.basename(filename)
            )
            part['Content-Disposition'] = 'attachment; filename="{0}"'.format(os.path.basename(filename))
            ## add mimetype based on the file extension
            mimetype = mimetypes.types_map["." + os.path.basename(filename).lower().split(".")[1]]
            part['Content-Type'] = mimetype + '; name="{0}"'.format(os.path.basename(filename))
            msgRoot.attach(part)

    # Send the email (this example assumes SMTP authentication is required)
    server = smtplib.SMTP('smtp.office365.com', 587)
    server.ehlo()
    server.starttls()
    server.ehlo()
    server.login(mailuser, mailpassword)
    server.sendmail(strFrom, emaillist, msgRoot.as_string())
    server.quit()

    logger.info("email sent.")

【问题讨论】:

    标签: python-3.x smtp office365


    【解决方案1】:

    想通了: 我正在将手动发送和发送的电子邮件源文件与我的 python 代码进行比较,我注意到 Content-Type 标头不同。 python代码使用'multipart/related',而手动发送使用'multipart/mixed'。这最终成为了问题。我将msgRoot = MIMEMultipart('related') 更改为msgRoot = MIMEMultipart(),这解决了问题。

    奇怪的是,python 代码发送的未加密电子邮件仍然可以正确显示并带有附件 - 只有安全电子邮件不能很好地与“多部分/相关”内容类型配合使用。我在一些使用“multipart/related”的示例代码上构建了我的代码,这就是我将它包含在我的原始代码中的原因。

    【讨论】:

      猜你喜欢
      • 2017-10-12
      • 2020-06-04
      • 2014-08-20
      • 1970-01-01
      • 1970-01-01
      • 2014-10-10
      • 2019-07-06
      • 2015-06-19
      • 2020-02-06
      相关资源
      最近更新 更多