How to get list of all active/accessible mailboxes from office 365 by logging in with an account having impersonation permissions

How to get list of all active/accessible mailboxes from office 365 by logging in with an account having impersonation permissions . Please share smaple c# code.

thanks

@ravikumarchopra,

You can get the mail boxes using following sample code.

        const string mailboxUri = "https://outlook.office365.com/ews/exchange.asmx";
        const string domain = @"";
        const string username = @"xxx.onmicrosoft.com";
        const string password = @"xxx";
        NetworkCredential credentials = new NetworkCredential(username, password, domain);
        IEWSClient client = EWSClient.GetEWSClient(mailboxUri, credentials);
        var cont = client.GetMailboxes();

Thanks for your reply. I will try this code.

I have another question, is there any way to find mailbox type such as: Shared Mailbox, Group mailbox and Regular mailbox etc.

mailbox-type.png (32.3 KB)

Thanks in Advance!!!

@ravikumarchopra,

I suggest you to please first try using the shared sample code. Once you access your mailboxes and traverse them, you will be able to access all of the requested one. Then you may make a logic on your end for accessing based on desired type.

Mudassir I tried the code client.GetMailboxes() returns an array of Contact type which contains some contacts in which there is no corresponding mailbox hope you understand my concern. so how to get the list of mailbox email ids having a corresponding accessible mailbox. please share sample c# code.

thanks

@ravikumarchopra,

I have not been able to understand following requirement.

Can you please share the test account along with snapshot of required information that you want to extract using Aspose.Email. We will look into that to help you further in this regard.

Mudasir , sorry for the inconvenience. I am sharing an Admin Account with Impersonation/Full Access Permissions. So you please login with this account and check when we get mailboxes using Client.Getmailboxes() it returns the Contact array which contains contacts with email having no corressponding office365 mailbox ( such as ravi@mailsdaddy, manoj@mailsdaddy ).

Username : manoj@sysbud.onmicrosoft.com
Password : @123Mails#!@#$

@ravikumarchopra,

I have tried to access the account. However, I am getting unauthorized exception for shared account. Can you please verify.

Hi Mudasir, its working at my end. You please try again by copy and pasting the provided username and password.

thanks

@ravikumarchopra,

I have been able to access the account now. However, I have created an issue with ID EMAILNET-39546 as investigation to further investigate the requirements shared by you. We will share the good news with you as soon as the issue will be fixed.

Hi,

It’s quite urgent so please fix and provide update as soon as possible.

Thanks

@ravikumarchopra,

sure, we are working on this and will good news with you soon.

I am still waiting for your reply.

@ravikumarchopra,

We have investigated the issue on our end. Unfortunately, EWS does not allow to provide list of users for which impersonation has been made.However, you may get all Exchange users in your organization. Then you may perform impersonation for each user from the retrieved list and try whether impersonation works.

This is only way to do that if you want to use only EWS client. Some fixes have been made, so you have to use latest version of the EWS client.

Also you have to set up integration between Azure AD and Office 365 to use OAuth authentication by following these guidelines. You can then consider using following sample code:

    public void test(TestServerType serverType)
    {
        TestServer server = TestUtil.GetServer(serverType);
        OAuthTestUser oAuthUser = server.User1;
        ITokenProvider tokenProvider = new AzureROPCTokenProvider(oAuthUser.Tenant, oAuthUser.ClientId, oAuthUser.EMail, oAuthUser.Password);
        OAuthNetworkCredential credentials = new OAuthNetworkCredential(tokenProvider);
        using (IEWSClient client = EWSClient.GetEWSClient(server.EWSUrl, credentials))
        {
            Contact[] mailboxCollection = client.GetMailboxes();
            // then check impersonation for each Contact (user) by email like described in article bellow
            // https://docs.aspose.com/display/emailnet/Utility+Features#UtilityFeatures-ExchangeImpersonation
            List<string> impersonatedMailboxes = new List<string>();
            foreach (Contact c in mailboxCollection)
            {
                client.ImpersonateUser(ItemChoice.PrimarySmtpAddress, c.EmailAddresses[0].Address);
                // try to execute any method for impersonated user
                try
                {
                    client.ListMailboxes();
                    impersonatedMailboxes.Add(c.EmailAddresses[0].Address);
                }
                catch { }
            }
            client.ResetImpersonation();
        }
    }

internal class AzureROPCTokenProvider : ITokenProvider
{
    private const string uriFormat = "https://login.microsoftonline.com/{0}/oauth2/v2.0/token";
    private const string bodyFormat =
        "client_id={0}" +
        "&scope={1}" +
        "&username={2}" +
        "&password={3}" +
        "&grant_type={4}";
    private readonly static string[] scopeAr = new string[]
    {
        // O365 ----------------------
        // Exchange Web Services will not receive feature updates
        // Basic Authentication for EWS will be decommissioned
        // https://developer.microsoft.com/en-us/graph/blogs/upcoming-changes-to-exchange-web-services-ews-api-for-office-365/

        "https://outlook.office.com/EWS.AccessAsUser.All",

    };
    private readonly static string scope = string.Join(" ", scopeAr);
    private const string grant_type = "password";
    private readonly object tokenSyncObj = new object();
    private OAuthToken token;
    private readonly string tenant;
    private readonly string clientId;
    private readonly string userName;
    private readonly string password;

    /// <summary>
    /// Initializes a new instance of the <see cref="AzureROPCTokenProvider"/> class
    /// </summary>
    /// <param name="tenant"></param>
    /// <param name="clientId"></param>
    /// <param name="scope"></param>
    /// <param name="userName"></param>
    /// <param name="password"></param>
    public AzureROPCTokenProvider(string tenant, string clientId, string userName, string password)
    {
        this.tenant = tenant;
        this.clientId = clientId;
        this.userName = userName;
        this.password = password;
    }

    /// <summary>
    /// Gets oAuth access token. 
    /// </summary>
    /// <param name="ignoreExistingToken">
    /// If ignoreExistingToken is true, requests new token from a server. Otherwise behaviour is depended on whether token exists or not.
    /// If token exists and its expiration date is not expired returns current token, otherwise requests new token from a server.
    /// </param>
    /// <returns>Returns oAuth access token</returns>
    public virtual OAuthToken GetAccessToken(bool ignoreExistingToken)
    {
        lock (tokenSyncObj)
        {
            if (this.token != null && !this.token.Expired && !ignoreExistingToken)
                return this.token;
            token = null;
            string uri = string.Format(uriFormat, tenant);
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
            string body = string.Format(bodyFormat,
                HttpUtility.UrlEncode(clientId),
                HttpUtility.UrlEncode(scope),
                HttpUtility.UrlEncode(userName),
                HttpUtility.UrlEncode(password),
                HttpUtility.UrlEncode(grant_type));
            byte[] bytes = Encoding.ASCII.GetBytes(body);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = bytes.Length;
            MemoryStream ms = new MemoryStream(bytes);
            using (Stream requestStream = request.GetRequestStream())
                requestStream.Write(bytes, 0, bytes.Length);
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StringBuilder responseText = new StringBuilder();
            bytes = new byte[1024];
            int read = 0;
            using (Stream stream = response.GetResponseStream())
            {
                while ((read = stream.Read(bytes, 0, bytes.Length)) > 0)
                    responseText.Append(Encoding.ASCII.GetString(bytes, 0, read));
            }
            string jsonString = responseText.ToString();
            AzureTokenResponse t = JsonConvert.DeserializeObject<AzureTokenResponse>(jsonString);
            token = new OAuthToken(
                t.access_token,
                TokenType.AccessToken,
                DateTime.Now.AddSeconds(t.expires_in));
            return token;
        }
    }

    /// <summary>
    /// Gets oAuth access token.
    /// If token exists and its expiration date is not expired returns current token, otherwise requests new token from a server.
    /// </summary>
    /// <returns>Returns oAuth access token</returns>
    public OAuthToken GetAccessToken()
    {
        return GetAccessToken(false);
    }

    /// <summary>
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    /// </summary>
    public virtual void Dispose()
    {
    }
}

public class AzureTokenResponse
{
    /// <summary>
    /// The requested access token. The calling web service can use this token to authenticate to the receiving web service.
    /// </summary>
    public string access_token { get; set; }

    /// <summary>
    /// Indicates the token type value. The only type that Azure AD supports is Bearer For more information about bearer tokens, 
    /// see The OAuth 2.0 Authorization Framework: Bearer Token Usage (RFC 6750).
    /// </summary>
    public string token_type { get; set; }

    /// <summary>
    /// How long the access token is valid (in seconds).
    /// </summary>
    public int expires_in { get; set; }

    /// <summary>
    /// How long the access token is valid (in seconds).
    /// </summary>
    public int ext_expires_in { get; set; }

    /// <summary>
    /// The time when the access token expires. 
    /// The date is represented as the number of seconds from 1970-01-01T00:00:00Z UTC until the expiration time.
    /// This value is used to determine the lifetime of cached tokens.
    /// </summary>
    public int expires_on { get; set; }

    /// <summary>
    /// The App ID URI of the receiving web service.
    /// </summary>
    public string resource { get; set; }

    /// <summary>
    /// If an access token was returned, this parameter lists the scopes the access token is valid for.
    /// </summary>
    public string scope { get; set; }

    /// <summary>
    /// Issued if the original scope parameter included the openid scope.
    /// </summary>
    public string id_token { get; set; }

    /// <summary>
    /// Issued if the original scope parameter included offline_access.
    /// </summary>
    public string refresh_token { get; set; }
}