Office 365 中可操作邮件的安全性要求Security requirements for actionable messages in Office 365

保护可操作邮件的操作非常简单方便。端到端体验中有两个阶段,当支持 Office 365 可操作邮件时会对服务施加安全性要求。阶段及其相应要求如下所示。Securing actionable email is simple and easy. There are two phases within the end-to-end experience that impose security requirements on your service when supporting actionable messages with Office 365. The phases and their corresponding requirements are as follows.

  1. 发送阶段:服务发送可操作邮件的先决条件如下所示:Send phase: The pre-requisites for your service to send actionable messages are as follows:
    • 如果要使用可操作电子邮件,需要启用发件人验证If you're using actionable email, you'll need to enable sender verification. 请注意,这不适用于连接器邮件。Note that this does not apply to connector messages.
    • 必须向 Microsoft 注册服务。Your service must be registered with Microsoft.
    • 操作 URL 必须支持 HTTPS。The Action URL must support HTTPS.
  2. 操作处理阶段:当处理某项操作时,服务应:Action processing phase: When processing an action, your service should:
    • 验证 HTTP POST 请求的标头中包含的持有者令牌(JSON Web 令牌)。还可以使用 Microsoft 提供的示例库完成此操作。Verify the bearer token (a JSON Web token) included in the header of the HTTP POST request. Verification can also be done leveraging the sample libraries provided by Microsoft.
    • 在目标 URL 中包含服务中的有限目的令牌,服务可使用它将服务 URL 与目标请求和用户关联起来。这是可选的,但强烈推荐。Include Limited Purpose Token from your service as part of the target URL, which can be used by your service to correlate the service URL with the intended request & user. This is optional, but highly recommended.

发件人验证Sender verification

Office 365 要求发件人验证,以通过电子邮件启用可操作邮件。Office 365 requires sender verification in order to enable actionable messages via email. 你的可操作电子邮件必须源自实施域密钥识别邮件 (DKIM) 和发件人策略框架 (SPF) 的服务器,或必须实施签名卡Your actionable message emails must either originate from servers that implement DomainKeys Identified Mail (DKIM) and Sender Policy Framework (SPF), or you must implement signed cards.

尽管 DKIM 和 SPF 对于一些应用场景已足够,但该解决方案并不适用于通过外部提供商发送电子邮件的某些应用场景,它可能会导致收件人无法体验增强的可操作邮件。While DKIM and SPF are sufficient for some scenarios, that solution will not work in some situations where emails are sent via an external provider, which can lead to recipients not experiencing the enhanced actionable message. 为此,我们建议始终实施签名卡,这在所有情况下均适用,并且从根本上来说,这样更为安全,因为它们并不依赖于 DNS 记录。For this reason, we recommend always implementing signed cards which work in all cases and are fundamentally more secure since they do not rely on DNS records.

实施 DKIM 和 SPFImplementing DKIM and SPF

DKIM 和 SPF 是在通过 SMTP 发送电子邮件时证明发件人身份的行业标准方法。DKIM and SPF are industry standard ways to prove a sender's identity when sending emails over SMTP. 很多公司已实施这些标准,用于保护已发送的电子邮件的安全。Many companies already implement these standards to secure the emails they are already sending. 若要详细了解 SPF/DKIM 以及如何实施,请参阅:To learn more about SPF/DKIM and how to implement them, see:

签名卡有效负载Signed card payloads

通过电子邮件发送的可操作邮件支持其他验证方法:可使用 RSA 密钥或 X509 证书对卡有效负载进行签名。Actionable messages sent via email support an alternative verification method: signing the card payload with an RSA key or X509 certificate. 此方法在以下应用场景中是必需的:This method is required in the following scenarios:

  • 因 Office 365 服务前的发件人设置或收件人租户设置自定义安全服务导致的 SPF/DKIM 故障。SPF/DKIM failure caused by sender setup or recipient tenant set custom security services in front of Office 365 services.
  • 可操作邮件的应用场景要求从多个电子邮件帐户发送。Your scenario for actionable messages requires sending from multiple email accounts.

要使用签名卡,必须在电子邮件开发人员仪表板中注册公钥,并使用相应的私钥对卡进行签名。To use signed cards, you must register your public key in the email developer dashboard, and use the corresponding private key to sign the card.

SignedCardSignedCard

通过电子邮件发送时,可使用签名的可操作邮件卡。Signed actionable message cards are available when sending via email. 使用此格式在电子邮件的 HTML 正文中添加签名卡。Use this format to include a signed card in the HTML body of an email. 此有效负载已使用附加到 HTML 正文末尾的 Microdata 格式序列化。This payload is serialized in Microdata format appended in the end of HTML body.

<section itemscope itemtype="http://schema.org/SignedAdaptiveCard">
    <meta itemprop="@context" content="http://schema.org/extensions" />
    <meta itemprop="@type" content="SignedAdaptiveCard" />
    <div itemprop="signedAdaptiveCard" style="mso-hide:all;display:none;max-height:0px;overflow:hidden;">[SignedCardPayload]</div>
</section>

注释:喜欢使用传统邮件卡片实体的合作伙伴可以创建 SignedMessageCard 实体,以替代 SignedAdaptiveCard。Note: Partners who prefer to use the legacy MessageCard entity may create a SignedMessageCard entity in place of a SignedAdaptiveCard.

SignedCardPayloadSignedCardPayload

SignedCardPayload 字符串采用 JSON Web 签名 (JWS) 标准编码。SignedCardPayload is a string encoded by JSON Web Signature (JWS) standard. RFC7515 介绍了 JWS,RFC7519 介绍了 JSON Web 令牌 (JWT)。RFC7515 describes JWS, and RFC7519 describes JSON Web Token (JWT). 如果 JWT 中无需任何声明,则可使用 JWT 库来构建 JWS 签名。Given no claim is required in JWT, JWT libraries can be used to build JWS signature.

注释:术语“JWT”在实际应用中可以互换使用。Note: The term "JWT" can be used interchangeably in practice. 但是,我们在此更偏向于使用“JWS”。However, we prefer the term "JWS" here.

下面是 SignedCardPayload 的示例。按照 JWS 规范,编码的自适应卡片以 [标题].[有效负载].[签名] 形式显示。Here is an example of SignedCardPayload. The encoded Adaptive Card appears in the form of [header].[payload].[signature] as per JWS specification.

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZW5kZXIiOiJzZXJ2aWNlLWFjY291bnRAY29udG9zby5jb20iLCJvcmlnaW5hdG9yIjoiNjVjNjgwZWYtMzZhNi00YTFiLWI4NGMtYTdiNWM2MTk4NzkyIiwicmVjaXBpZW50c1NlcmlhbGl6ZWQiOiJbXCJqb2huQGNvbnRvc28uY29tXCIsXCJqYW5lQGNvbnRvc28uY29tXCJdIiwiYWRhcHRpdmVDYXJkU2VyaWFsaXplZCI6IntcIiRzY2hlbWFcIjpcImh0dHA6Ly9hZGFwdGl2ZWNhcmRzLmlvL3NjaGVtYXMvYWRhcHRpdmUtY2FyZC5qc29uXCIsXCJ0eXBlXCI6XCJBZGFwdGl2ZUNhcmRcIixcInZlcnNpb25cIjpcIjEuMFwiLFwiYm9keVwiOlt7XCJzaXplXCI6XCJsYXJnZVwiLFwidGV4dFwiOlwiSGVsbG8gQWN0aW9uYWJsZSBtZXNzYWdlXCIsXCJ3cmFwXCI6dHJ1ZSxcInR5cGVcIjpcIlRleHRCbG9ja1wifV0sXCJhY3Rpb25zXCI6W3tcInR5cGVcIjpcIkFjdGlvbi5JbnZva2VBZGRJbkNvbW1hbmRcIixcInRpdGxlXCI6XCJPcGVuIEFjdGlvbmFibGUgTWVzc2FnZXMgRGVidWdnZXJcIixcImFkZEluSWRcIjpcIjNkMTQwOGY2LWFmYjMtNGJhZi1hYWNkLTU1Y2Q4NjdiYjBmYVwiLFwiZGVza3RvcENvbW1hbmRJZFwiOlwiYW1EZWJ1Z2dlck9wZW5QYW5lQnV0dG9uXCJ9XX0iLCJpYXQiOjE1NDUzNDgxNTN9.BP9mK33S1VZyjtWZd-lNTTjvueyeeoitygw9bl17TeQFTUDh9Kg5cB3fB7BeZYQs6IiWa1VGRdiiR4q9EkAB1qDsmIcJnw6aYwDUZ1KY4lNoYgQCH__FxEPHViGidNGtq1vAC6ODw0oIfaTUWTa5cF5MfiRBIhpQ530mbRNnA0QSrBYtyB54EDJxjBF1vNSKOeVHAl2d4gqcGxsytQA0PA7XMbrZ8B7fEU2uNjSiLQpoh6A1tevpla2C7W6h-Wekgsmjpw2YToAOX67VZ1TcS5oZAHmjv2RhqsfX5DlN-ZsTRErU4Hs5d92NY9ijJPDunSLyUFNCw7HLNPFqqPmZsw

以上 JWS 中的标头为:The header in above JWS is:

{
  "alg": "RS256",
  "typ": "JWT"
}

以上 JWS 中的有效负载为:The payload in above JWS is:

{
  "sender": "service-account@contoso.com",
  "originator": "65c680ef-36a6-4a1b-b84c-a7b5c6198792",
  "recipientsSerialized": "[\"john@contoso.com\",\"jane@contoso.com\"]",
  "adaptiveCardSerialized": "{\"$schema\":\"http://adaptivecards.io/schemas/adaptive-card.json\",\"type\":\"AdaptiveCard\",\"version\":\"1.0\",\"body\":[{\"size\":\"large\",\"text\":\"Hello Actionable message\",\"wrap\":true,\"type\":\"TextBlock\"}],\"actions\":[{\"type\":\"Action.InvokeAddInCommand\",\"title\":\"Open Actionable Messages Debugger\",\"addInId\":\"3d1408f6-afb3-4baf-aacd-55cd867bb0fa\",\"desktopCommandId\":\"amDebuggerOpenPaneButton\"}]}",
  "iat": 1545348153
}
必需的声明Required Claims
声明Claim 描述Description
originator 必须设置为在载入时由 Microsoft 提供的 ID。MUST be set to the ID provided by Microsoft during onboarding.
iat 签名有效负载的时间。The time that the payload was signed.
sender 用于发送此可操作邮件的电子邮件地址。The email address used to send this actionable message.
recipientsSerialized 电子邮件收件人的字符串化列表。The stringified list of the recipients of the email. 该列表应包括电子邮件的所有收件人/抄送收件人。This should include all the To/CC recipients of the email.
adaptiveCardSerialized 字符串化自适应卡片。The stringified Adaptive Card.

生成已签名卡片的示例代码:Sample code generating signed card:

验证该请求是否来自 MicrosoftVerifying that requests come from Microsoft

Microsoft 的所有操作请求均在 HTTP Authorization 标头中具有持有者令牌。此令牌是 Microsoft 签名的 JSON Web 令牌 (JWT),而且其中还包括我们强烈建议应由处理相关请求的服务验证的重要声明。All action requests from Microsoft have a bearer token in the HTTP Authorization header. This token is a JSON Web Token (JWT) token signed by Microsoft, and it includes important claims that we strongly recommend should be verified by the service handling the associated request.

声明名称Claim name Value
aud 目标服务的基本 URL,例如 https://api.contoso.comThe base URL of the target service, e.g. https://api.contoso.com
iss 令牌的颁发者。The issuer of the token. 这应该是 https://substrate.office.com/sts/This should be https://substrate.office.com/sts/
sub 采取行动的用户的标识。对于通过电子邮件发送的可操作邮件,sub 将是用户的电子邮件地址。对于连接器,sub 将是采取行动的用户的 objectID。The identity of the user who took the action. For Actionable Messages sent over email, sub would be the email address of the user. For connectors, sub will be the objectID of the user who took the action.
sender 包含该操作的邮件的发件人标识。The identity of sender of the message containing the action. 只有在 通过电子邮件发送 可操作性邮件时,此值才会显示。This value is only present if the actionable message was sent via email. 通过连接器发送 的邮件在持有者令牌中不包含此声明。Actionable messages sent via connectors do not include this claim in their bearer token.

通常,服务将执行以下验证。Typically, a service will perform the following verifications.

  1. 该令牌由 Microsoft 签名。The token is signed by Microsoft. OpenID 元数据位于 https://substrate.office.com/sts/common/.well-known/openid-configuration,其中包括有关签名密钥的信息。OpenID metadata is located at https://substrate.office.com/sts/common/.well-known/openid-configuration, which includes information regarding signing keys.
  2. aud 声明对应于服务的基本 URL。The aud claim corresponds to the service's base URL.

完成上述所有验证后,服务就可以信任 sendersub 声明是以发件人和执行操作的用户身份发出的。服务可验证 sendersub 声明是否与预期的发件人和用户匹配。With all the above verifications done, the service can trust the sender and sub claims to be the identity of the sender and the user taking the action. The service can validate that the sender and sub claims match the sender and user it is expecting.

请参考以下 Microsoft 代码示例,其中展示了如何对 JWT 令牌执行这些验证。Please refer to the Microsoft code samples provided below, which show how to do these validations on the JWT token.

Action-Authorization 标头Action-Authorization header

可操作邮件使用 Authorization 标头可能会干扰目标终结点的现有身份认证/授权机制。The use of Authorization header by Actionable messages may interfere with existing authentication/authorization mechanism for the target endpoint. 在这种情况下,开发人员可以将 Authorization 标头设置为 null 或在 Action.Http 操作的 headers 属性中设置一个空字符串。In this case, developers can set the Authorization header to null or an empty string in the headers property of an Action.Http action. 然后,可操作邮件将通过 Action-Authorization 标头而不使用 Authorization 标头发送相同的持有者令牌。Actionable messages will then send the same bearer token via Action-Authorization header instead of using Authorization header.

提示

如果 Authorization 标头包含通过可操作邮件设置的持有者令牌,则 Azure 逻辑应用服务将返回 HTTP 401 UnauthorizedThe Azure Logic App service returns HTTP 401 Unauthorized if the Authorization header contains the bearer token set by actionable messages.

带有 Action-Authorization 标头的示例 Action.HttpExample Action.Http with Action-Authorization header

{
  "type": "Action.Http",
  "title": "Say hello",
  "method": "POST",
  "url": "https://api.contoso.com/sayhello",
  "body": "{{nameInput.value}}",
  "headers": [
    { "name": "Authorization", "value": "" }
  ]
}

验证用户的标识Verifying the identity of the user

所有请求随附的持有者令牌都包括执行此操作的 Office 365 用户的 Azure AD 标识。The bearer token included with all requests includes the Azure AD identity of the Office 365 user who took the action. 如有必要,可将特定于服务的令牌添加到 HTTP 操作的 URL 中,用于表示系统中的用户标识。If necessary, you can include your own token, specific to your service, in the URLs of your HTTP actions to represent the identity of the user in your system. Microsoft 并未规定如何设计有限访问令牌或服务应如何使用该令牌。Microsoft does not prescribe how the limited-access tokens should be designed or used by the service. 此令牌对于 Microsoft 来说并不透明,并且只会返回到服务。This token is opaque to Microsoft, and is simply echoed back to the service.

特定于服务的令牌可用于关联服务 URL 与特定邮件和用户。Microsoft 建议如果使用自己的特定于服务的令牌,可将该令牌作为操作目标 URL 的一部分,或包括在返回该服务的请求正文中。例如:Service-specific tokens can be used to correlate service URLs with specific messages and users. Microsoft recommends that if you use your own service-specific token, youinclude it as part of the action target URL, or in the body of the request coming back to the service. For example:

https://contoso.com/approve?requestId=abc&serviceToken=a1b2c3d4e5...

服务特定令牌用作关联 ID(例如使用 userID、requestID 和加密盐的哈希令牌)。这允许服务提供商跟踪其生成和发送的操作 URL,并将其与进入的操作请求匹配。除了关联,服务提供商还可以使用服务特定令牌保护自身免受重放攻击。例如,如果以前已使用同一令牌执行操作,服务提供商可选择拒绝该请求。Service-specific tokens act as correlation IDs (for e.g. a hashed token using the userID, requestID, and salt). This allows the service provider to keep track of the action URLs it generates and sends out and match it with action requests coming in. In addition to correlation, the service provider may use the service-specific token to protect itself from replay attacks. For example, the service provider may choose to reject the request, if the action was already performed previously with the same token.