Я получаю ошибку «401 Unauthorized», когда «UseDefaultCredentials» имеет значение True - PullRequest
0 голосов
/ 02 апреля 2019

Когда я указываю имя пользователя и пароль в вызове в WebCredentials , мои вызовы в EWS работают нормально.Если для свойства ExchangeService.UseDefaultCredentials установить значение True, я получу сообщение 401 Несанкционированная ошибка.

Я не знаю, важно ли это, но наш администратор 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("user@company.com", "password")"
                // Then Everything works fine.
                //------------------------------------------------
                _service.UseDefaultCredentials = true;
                //_service.Credentials = new WebCredentials("user@company.com", "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, "delegator@company.com"), 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;
            }
        }
    }
}

Ответы [ 2 ]

1 голос
/ 03 апреля 2019

Если ваши почтовые ящики находятся на 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 с библиотекой ADAL https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/AcquireTokenSilentAsync-using-Integrated-authentication-on-Windows-(Kerberos), чтобы воспользоваться преимуществами текущего пользователя.

0 голосов
/ 02 апреля 2019

Наши учетные записи находятся на Exchange Online.Вот почему установка UseDefaultCredentials на True не имеет никакого эффекта.

от Microsoft

Вы не можете использоватьучетные данные по умолчанию для вошедшего в систему пользователя, если почтовый ящик пользователя размещен в Exchange Online или Exchange Online как часть Office 365. Вместо этого используйте свойство Credentials, чтобы установить учетные данные пользователя.Учетные данные пользователя должны быть в форме имени участника-пользователя (UPN) для Exchange Online.

...