使用OAuth2认证结合EWS实现实时读取邮件功能

发布于:2022-12-27 ⋅ 阅读:(655) ⋅ 点赞:(0)

公司之前有一个进行邮件获取的功能,使用ExchangeService+TLS1.2认证的方式,但是由于微软将要将这种认证方式列为Legacy authentication,且将在2022年10月下载该认证方式。因此将尝试使用OAuth+EWS这种认证的方式。别问问啥必须用微软系的功能,问就是公司硬性要求。

如下为更改通知:

Stop legacy authentication:

Microsoft have announced that Exchange online – will stop allowing legacy authentication from October 2022

I am writing to you – because you are registered as owner of an account used for legacy authentication. (Legacy authentication is basically using username / password for authentication)

Reason

The reason why Microsoft  choose to remove support is Legacy authentication is that it considered insecure and added a risk to XXXXXXXXXXXX for password spray attacks.

Information

The spreadsheet included is also published here and general information on changes in the cloud: Information on changes in Azure for developers and on-line services (sharepoint.com)

The notification from Microsoft: Basic Authentication and Exchange Online – September 2021 Update - Microsoft Tech Community

Near Future

It is planned to block Legacy Authentication for new systems – in very near future.

开始之前,先看一下下文中Delegated权限和Application权限的区别:

使用 OAuth 对 EWS 应用程序进行身份验证

一、使用OAuth2认证申请

1、申请AppID,tenantID

管理员在AAD(Azure Active Directory)进行App 注册。注册完毕之后会生产Application (client) ID(APPID)和一个Directory (tenant) ID (租户ID)

 2、申请secrets

按照如下图步骤,

注意:

        1、在选择过期日期时,默认为6个月,可手动修改为24个月

        2、生产的Value值只会在首次添加完成之后出现,所以添加完成之后,将步骤2中Value值保存下来

 

 3、添加授权权限

 点击左侧的API Permission 链接,添加如下的权限

  注意:如果你是管理员,那么你可以添加Application类型的权限,否则你只能添加Delegation类型的权限

二、Policy授权

需要EWS的管理原将你要获取的邮箱地址配置到EWS服务器中,将应用程序权限限制为特定 Exchange Online 邮箱

可参考:添加特定邮箱地址的ApplicationAccessPolicy

授权完毕之后,进行查看,如出现如下内容,则表示添加完毕。

 三、C#代码编写

1、Config文件配置第一步骤中生成的三个ID

<!-- The application ID from your app registration -->
<add key="appId" value="{{YOUR APP ID}}" />
<!-- The tenant ID copied from your app registration -->
<add key="tenantId" value="{{YOUR TENANTID}}"/>
<!-- The application's client secret from your app registration. Needed for application permission access -->
<add key="clientSecret" value="{{YOUR SECRET ID}}"/>

2、代码执行逻辑

using Microsoft.Exchange.WebServices.Data;
using Microsoft.Identity.Client;
using Quartz;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks; 

public async System.Threading.Tasks.Task GetEmailByOAuth()
 {
var cca = ConfidentialClientApplicationBuilder
                .Create(ConfigurationManager.AppSettings["appId"])
                .WithClientSecret(ConfigurationManager.AppSettings["clientSecret"])
                .WithTenantId(ConfigurationManager.AppSettings["tenantId"])
                .Build();

            var ewsScopes = new string[] { "https://outlook.office365.com/.default" };

           
                var authResult = await cca.AcquireTokenForClient(ewsScopes).ExecuteAsync();

                var ewsClient = new ExchangeService();
                ewsClient.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
                ewsClient.Credentials = new OAuthCredentials(authResult.AccessToken);
                ewsClient.ImpersonatedUserId =
                    new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "{{你将要访问的邮箱地址,注意该地址必须是第二步骤中添加Policy中的地址,否则会提示403,禁止访问}}");

                ewsClient.HttpHeaders.Add("X-AnchorMailbox", "{{你将要访问的邮箱地址,注意该地址必须是第二步骤中添加Policy中的地址,否则会提示403,禁止访问}}");

                int offset = 0;
                int pageSize = 100;
                bool more = true;
                ItemView itemViews = new ItemView(pageSize, offset);

                PropertySet itemPorpertySet = new PropertySet(BasePropertySet.FirstClassProperties,
                    EmailMessageSchema.MimeContent);
                //获取邮箱中的文件夹,如:收件箱,草稿箱,日历等等
                //var findFolders = ewsClient.FindFolders(WellKnownFolderName.MsgFolderRoot, SetFilter(), view);


                //获取收件箱中的具体邮件内容
                FindItemsResults<Item> findResults = ewsClient.FindItems(WellKnownFolderName.Inbox, SetFilter(), itemViews);
}

3、测试

当如上代码执行到最下面一行,如果验证findResults.Items.Count()>0,则验证成功,表示可正常获取邮箱地址中的邮件内容。至此,邮件审批功能修改完毕。

四、总结

以上步骤都是一个坑一个坑趟出来的,只写了正常执行的情况,当然,在正常从头开始做的时候,肯定会遇到很多的问题,都没有单独的列出来,如果读者也在使用这种方式,途中也遇到了各种各样的问题,请看官老爷留言,咱么一起学习,一起进步


网站公告

今日签到

点亮在社区的每一天
去签到