当“UseDefaultCredentials”设置为True时,我收到“401 Unauthorized”错误

问题描述 投票:0回答:2

当我在WebCredentials的调用中指定用户名和密码时,我对EWS的调用工作正常。如果我将ExchangeService.UseDefaultCredentials属性设置为True,则会收到401 Unauthorized错误。

我不知道这是否重要,但我们的Exchange管理员告诉我,我在混合环境中工作。我们正在运行Exchange Online和Exchange 2010(或2013年,我认为)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Exchange.WebServices.Data;
using System.Security.Cryptography.X509Certificates;
using System.Net; 

namespace EWSLib
{
    class Program
    {
        static ExchangeService _service;
        static void Main(string[] args)
        {
            string defaultEmail = System.DirectoryServices.AccountManagement.UserPrincipal.Current.EmailAddress;            
            ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;


            try
            {
                _service = new ExchangeService();

                Appointment meeting = new Appointment(_service);

                //-----------------------------------------------
                // If I comment out
                // "_service.UseDefaultCredentials = true" 
                // and uncomment the line "_service.Credentials = new WebCredentials("[email protected]", "password")"
                // Then Everything works fine.
                //------------------------------------------------
                _service.UseDefaultCredentials = true;
                //_service.Credentials = new WebCredentials("[email protected]", "password");


                _service.TraceEnabled = true;
                _service.TraceFlags = TraceFlags.All;
                //_service.AutodiscoverUrl(defaultEmail, RedirectionUrlValidationCallback);
                _service.Url = new Uri("https://example.com/EWS/Exchange.asmx");

                // TEST MEETING
                meeting.Subject = "The subject";
                meeting.Body = "The boddy";
                meeting.Start = DateTime.UtcNow.AddDays(5);
                meeting.End = DateTime.UtcNow.AddDays(5).AddHours(1);
                meeting.Location = "Someplace";
                meeting.IsReminderSet = true;



                meeting.RequiredAttendees.Add(defaultEmail);
                meeting.ReminderMinutesBeforeStart = 60;


                // Delegation
                meeting.Save(new FolderId(WellKnownFolderName.Calendar, "[email protected]"), SendInvitationsMode.SendToAllAndSaveCopy);



                // Verify that the meeting was created.
                Item item = Item.Bind(_service, meeting.Id, new PropertySet(ItemSchema.Subject));




            }
            catch (Exception e)
            {
                //System.Diagnostics.Debug.WriteLine(e);
                Console.WriteLine(e);
            }

            Console.ReadLine();
        }

        private static bool RedirectionUrlValidationCallback(string redirectionUrl)
        {
            // The default for the validation callback is to reject the URL.
            bool result = false;
            Uri redirectionUri = new Uri(redirectionUrl);
            // Validate the contents of the redirection URL. In this simple validation
            // callback, the redirection URL is considered valid if it is using HTTPS
            // to encrypt the authentication credentials. 
            if (redirectionUri.Scheme == "https")
            {


                result = true;
            }
            return result;
        }

        private static bool CertificateValidationCallBack(
    object sender,
        System.Security.Cryptography.X509Certificates.X509Certificate certificate,
    System.Security.Cryptography.X509Certificates.X509Chain chain,
    System.Net.Security.SslPolicyErrors sslPolicyErrors)
        {
            // If the certificate is a valid, signed certificate, return true.
            if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
            {
                Console.WriteLine("Valid Signed Certificate");
                return true;
            }

            // If there are errors in the certificate chain, look at each error to determine the cause.
            if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
            {
                if (chain != null && chain.ChainStatus != null)
                {
                    foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
                    {
                        if ((certificate.Subject == certificate.Issuer) &&
                       (status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
                        {
                        // Self-signed certificates with an untrusted root are valid. 
                            Console.WriteLine("Self-signed certificates with an untrusted root are valid.");
                            continue;
                        }
                        else
                        {
                            if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
                            {
                                // If there are any other errors in the certificate chain, the certificate is invalid,
                                // so the method returns false.
                                Console.WriteLine("there are any other errors in the certificate chain");
                                return false;
                            }
                        }
                    }
                }

                // When processing reaches this line, the only errors in the certificate chain are 
                // untrusted root errors for self-signed certificates. These certificates are valid
                // for default Exchange server installations, so return true.
                Console.WriteLine("Valid for some reason");
                return true;
            }
            else
            {
                // In all other cases, return false.
                Console.WriteLine("there are any other errors in the certificate chain");
                return false;
            }
        }
    }
}
exchangewebservices ews-managed-api
2个回答
1
投票

如果您的邮箱在Office365上,那么我建议您使用Oauth。明年,EWS https://blogs.technet.microsoft.com/exchange/2018/07/03/upcoming-changes-to-exchange-web-services-ews-api-for-office-365/的基本认证将会消失。

如果您使用oAuth,那么您可以使用Windows集成Auth和ADAL库https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/AcquireTokenSilentAsync-using-Integrated-authentication-on-Windows-(Kerberos)来利用当前登录的用户。


0
投票

我们的用户帐户位于Exchange Online上。这就是将UseDefaultCredentials设置为True的原因无效。

From Microsoft

如果用户的邮箱作为Office 365的一部分托管在Exchange Online或Exchange Online中,则无法使用登录用户的默认凭据。而是使用“凭据”属性设置用户的凭据。用户的凭据必须是Exchange Online的用户主体名称(UPN)表单。

© www.soinside.com 2019 - 2024. All rights reserved.