/// <summary>
        /// Try to get a new access token for this resource using a refresh token.
        /// If successful, this method will cache the access token for future use.
        /// If this fails, return null, signaling the caller to do the OAuth redirect.
        /// </summary>
        private static string GetAccessTokenFromRefreshToken(string resourceId)
        {
            string refreshToken = Office365Cache.GetRefreshToken().Value;

            if (refreshToken == null)
            {
                // If no refresh token, the caller will need to send the user to do an OAuth redirect.
                return(null);
            }

            // Redeem the refresh token for an access token:
            try
            {
                ClientCredential      credential  = new ClientCredential(AppPrincipalId, AppKey);
                string                authority   = string.Format(CultureInfo.InvariantCulture, OAuthUrl, "common");
                AuthenticationContext authContext = new AuthenticationContext(authority);
                AuthenticationResult  result      = authContext.AcquireTokenByRefreshToken(
                    refreshToken, AppPrincipalId, credential, resourceId);

                // Cache the access token and update the refresh token:
                Office365Cache.GetAccessToken(resourceId).Value = result.AccessToken;
                Office365Cache.GetRefreshToken().Value = result.RefreshToken;

                return(result.AccessToken);
            }
            catch (ActiveDirectoryAuthenticationException)
            {
                // Forget the refresh token and return null, so as to start the OAuth redirect from scratch.
                Office365Cache.GetRefreshToken().RemoveFromCache();
                return(null);
            }
        }
Beispiel #2
0
        public static OneDriveAccessDetails GetUsersOneDriveAccessDetails(string userEmail)
        {
            try
            {
                // Get the user's config, which contains the refresh token
                // and the OneDrive resource ID
                Storage.AppConfig appConfig = Storage.AppConfigCache.GetUserConfig(userEmail);

                // Request authorization for OneDrive
                ClientCredential      credential  = new ClientCredential(ClientId, ClientSecret);
                string                authority   = string.Format(CultureInfo.InvariantCulture, OAuthUrl, "common");
                AuthenticationContext authContext = new AuthenticationContext(authority);
                AuthenticationResult  result      = authContext.AcquireTokenByRefreshToken(
                    appConfig.RefreshToken, ClientId, credential, appConfig.OneDriveResourceId);

                // Update refresh token
                appConfig.RefreshToken = result.RefreshToken;
                Storage.AppConfigCache.AddUserConfig(userEmail, appConfig);

                return(new OneDriveAccessDetails()
                {
                    ApiEndpoint = appConfig.OneDriveApiEndpoint,
                    AccessToken = result.AccessToken
                });
            }
            catch (ActiveDirectoryAuthenticationException)
            {
                return(null);
            }
        }
        public string RefreshAccessToken(FormCollection form)
        {
            string spWebUrl = form["spWebUrl"];
            string tenantId = form["tenantId"];

            string refreshTokenContent = _refreshTokenManager.RetrieveToken(HttpContext.Request);

            var credential  = new ClientCredential(SettingsHelper.ClientId, SettingsHelper.ClientKey);
            var authContext = new AuthenticationContext(SettingsHelper.AUTHORITY + tenantId);

            try
            {
                AuthenticationResult result = authContext.AcquireTokenByRefreshToken(refreshTokenContent, credential, spWebUrl);

                if (result == null)
                {
                    throw new Exception("Error acquiring SharePoint AccessToken.");
                }

                return(result.AccessToken);
            }
            catch (AdalServiceException exception)
            {
                throw new Exception("SharePoint RefreshToken is invalid.", exception);
            }
        }
Beispiel #4
0
        private Tuple <string, DateTimeOffset> RenewAccessToken()
        {
            AuthenticationResult authResult = _authContext.AcquireTokenByRefreshToken(RefreshToken,
                                                                                      ConfigurationManager.AppSettings["ida:ClientId"],
                                                                                      _clientCredential,
                                                                                      ConfigurationManager.AppSettings["ida:ResourceUrl"]);

            return(new Tuple <string, DateTimeOffset>(authResult.AccessToken, authResult.ExpiresOn));
        }
        /// <summary>
        /// Renews the access token using refresh token
        /// </summary>
        /// <returns></returns>
        private static Tuple <string, DateTimeOffset> RenewAccessTokenUsingRefreshToken()
        {
            var authResult = _authenticationContext.AcquireTokenByRefreshToken(
                RefreshToken,
                _clientCredential,
                _resourceUrl);

            return(new Tuple <string, DateTimeOffset>(authResult.AccessToken, authResult.ExpiresOn));
        }
Beispiel #6
0
        public static string GetAccessTokenFromRefreshToken(string tenantId, string resourceId)
        {
            //
            // Try to get a new access token for this resource using a refresh token.
            // If this fails, return null signalling the caller to do an OpenID Connect sign-in request.
            //
            AuthenticationResult result = null;
            string refreshToken         = null;

            //
            // Fetch the refresh token from the cache
            //
            refreshToken = (string)GetRefreshTokenFromCache();
            if (refreshToken == null)
            {
                //
                // No refresh token - the caller will need to send the user to get an auth code.  Return null.
                //
                return(null);
            }

            try
            {
                //
                // Redeem the refresh token for an access token
                //
                ClientCredential      clientcred  = new ClientCredential(clientId, AppKey);
                string                authority   = String.Format(CultureInfo.InvariantCulture, aadInstance, tenantId);
                AuthenticationContext authcontext = new AuthenticationContext(authority);
                result = authcontext.AcquireTokenByRefreshToken(refreshToken, clientId, clientcred, resourceId);

                //
                // Save the authorization header for this resource and the refresh token in separate cookies
                //
                SaveAccessTokenInCache(resourceId, result.AccessToken, (result.ExpiresOn.AddMinutes(-5)).ToString());
                SaveRefreshTokenInCache(result.RefreshToken);

                return(result.AccessToken);
            }
            catch
            {
                //
                // If the refresh token is also expired, remove it from the cache, and send the user off to do an OpenID Connect sign-in request.
                //
                RemoveRefreshTokenFromCache();

                return(null);
            }
        }
Beispiel #7
0
        private static async Task <AuthenticationResult> GetManagementAccessResult(string refreshToken)
        {
            var authenticationContext = new AuthenticationContext(string.Format("https://login.microsoftonline.com/{0}/", SubscriptionTenant));
            var result = authenticationContext.AcquireTokenByRefreshToken(refreshToken, NativeClientId, "https://management.azure.com/");

            if (result == null)
            {
                throw new InvalidOperationException("Failed to obtain the JWT token");
            }

            string token = result.AccessToken;

            Console.WriteLine("Token\n\n" + token + "\n\n=====================\n\n\n\n\n");
            return(result);
        }
        public static void RefreshAccessToken(this ApiManagementClient apiManagementClient)
        {
            if (HttpMockServer.Mode == HttpRecorderMode.Playback)
            {
                // if it's playback then do nothing
                return;
            }

            var testEnvironment = new CSMTestEnvironmentFactory().GetTestEnvironment();
            var context         = new AuthenticationContext(new Uri(testEnvironment.Endpoints.AADAuthUri, testEnvironment.Tenant).AbsoluteUri);

            var result   = context.AcquireToken("https://management.core.windows.net/", testEnvironment.ClientId, new Uri("urn:ietf:wg:oauth:2.0:oob"), PromptBehavior.Auto);
            var newToken = context.AcquireTokenByRefreshToken(result.RefreshToken, testEnvironment.ClientId, "https://management.core.windows.net/");

            ((TokenCloudCredentials)apiManagementClient.Credentials).Token = newToken.AccessToken;
        }
        private AuthenticationResult GetTokenByRefreshToken(AuthenticationResult authenticationResult, AuthenticationContext authContext, string ClientId, string resourceId)
        {
            if (authenticationResult != null && !string.IsNullOrEmpty(authenticationResult.AccessToken))
            {
                JwtSecurityToken securityToken = new JwtSecurityToken(authenticationResult.AccessToken);
                if (securityToken != null)
                {
                    //// If token is going to expire in next 15 minutes.
                    if (securityToken != null && securityToken.ValidTo.AddMinutes(-15) <= DateTime.UtcNow)
                    {
                        return(authContext.AcquireTokenByRefreshToken(authenticationResult.RefreshToken, ClientId, resourceId));
                    }
                }
            }

            return(null);
        }
Beispiel #10
0
        public ActionResult RefreshAccessToken()
        {
            string refreshToken = CustomAuthenticationManager.GetRefreshToken();

            ClientCredential credential =
                new ClientCredential(DemoConstants.ClientId, DemoConstants.ClientSecret);

            string resource = DemoConstants.TargetResource;

            AuthenticationContext authenticationContext =
                new AuthenticationContext(DemoConstants.urlAuthorizationEndpoint);

            AuthenticationResult authenticationResult =
                authenticationContext.AcquireTokenByRefreshToken(refreshToken, credential, resource);

            CustomAuthenticationManager.RefreshAccessToken(authenticationResult);

            return(RedirectToAction("AccessToken", "TokenViewer"));
        }
Beispiel #11
0
        public string GetBearerToken()
        {
            string resourceUri       = "https://analysis.windows.net/powerbi/api";
            Claim  userObjectIdClaim = ClaimsPrincipal.Current.FindFirst(Globals.ObjectIdClaimType);
            Claim  tenantIdClaim     = ClaimsPrincipal.Current.FindFirst(Globals.TenantIdClaimType);

            if (userObjectIdClaim != null && tenantIdClaim != null)
            {
                var authContext = new AuthenticationContext(
                    String.Format(CultureInfo.InvariantCulture, ConfigHelper.AadInstance, tenantIdClaim.Value),
                    new TokenDbCache(userObjectIdClaim.Value));
                var code  = authContext.TokenCache.ReadItems().First().RefreshToken;
                var token = authContext.AcquireTokenByRefreshToken(code, new ClientCredential(ConfigHelper.ClientId, ConfigHelper.AppKey), resourceUri);

                return(token.CreateAuthorizationHeader());
            }

            throw new UnauthorizedAccessException();
        }
        /// <summary>
        /// Try to get a new access token for this resource using a refresh token.
        /// If successful, this method will cache the access token for future use.
        /// If this fails, return null, signaling the caller to do the OAuth redirect.
        /// </summary>
        public static string GetAccessTokenFromRefreshToken(string resourceId)
        {
            // Redeem the refresh token for an access token:
            try
            {
                string                refreshToken = Storage.SecureStore.RefreshToken;
                ClientCredential      credential   = new ClientCredential(ClientId, ClientSecret);
                string                authority    = string.Format(CultureInfo.InvariantCulture, OAuthUrl, "common");
                AuthenticationContext authContext  = new AuthenticationContext(authority);
                AuthenticationResult  result       = authContext.AcquireTokenByRefreshToken(
                    refreshToken, ClientId, credential, resourceId);

                return(result.AccessToken);
            }
            catch (ActiveDirectoryAuthenticationException)
            {
                return(null);
            }
        }
Beispiel #13
0
        public bool Authenticate()
        {
            _token = string.Empty;

            AuthenticationContext authContext = new AuthenticationContext(_authorityUri);

            if (!File.Exists("token.txt"))
            {
                AuthenticationResult ar = authContext.AcquireToken(_resourceUri, _clientId, new Uri(_redirectUri));
                _token = ar.AccessToken;
                File.WriteAllText("token.txt", ar.RefreshToken);
            }
            else
            {
                string refreshToken     = File.ReadAllText("token.txt");
                AuthenticationResult ar = authContext.AcquireTokenByRefreshToken(refreshToken, _clientId);
                _token = ar.AccessToken;
            }

            return(!string.IsNullOrEmpty(_token));
        }
        private AuthenticationResult GetAccessTokenFromAzureAD(Uri orgUrl)
        {
            var clientSecret = CryptoManager.Decrypt(_connection.S2SClientSecret, ConnectionManager.CryptoPassPhrase,
                                                     ConnectionManager.CryptoSaltValue,
                                                     ConnectionManager.CryptoHashAlgorythm,
                                                     ConnectionManager.CryptoPasswordIterations,
                                                     ConnectionManager.CryptoInitVector,
                                                     ConnectionManager.CryptoKeySize);

            var credentials = new ClientCredential(_connection.AzureAdAppId.ToString(), clientSecret);
            var parameters  = AuthenticationParameters.CreateFromResourceUrlAsync(orgUrl).Result;
            var context     = new AuthenticationContext(parameters.Authority);
            var result      = context.AcquireTokenByRefreshToken(_connection.RefreshToken, credentials, parameters.Resource);

            if (!String.IsNullOrEmpty(result.RefreshToken))
            {
                _connection.RefreshToken = result.RefreshToken;
            }

            return(result);
        }
Beispiel #15
0
        /// <summary>
        /// Gets the access token.
        /// </summary>
        /// <param name="biAccountValue">The bi account value.</param>
        /// <param name="message">The message.</param>
        /// <returns></returns>
        private static string GetAccessToken(DefinedValueCache biAccountValue, out string message)
        {
            message = string.Empty;
            string accessCode = string.Empty;

            if (biAccountValue != null)
            {
                var refreshToken = biAccountValue.AttributeValues.Where(v => v.Key == "RefreshToken").Select(v => v.Value.Value).FirstOrDefault();
                var clientId     = biAccountValue.AttributeValues.Where(v => v.Key == "ClientId").Select(v => v.Value.Value).FirstOrDefault();
                var clientSecret = biAccountValue.AttributeValues.Where(v => v.Key == "ClientSecret").Select(v => v.Value.Value).FirstOrDefault();

                try
                {
                    TokenCache            TC = new TokenCache();
                    AuthenticationContext AC = new AuthenticationContext(PowerBiUtilities.AuthorityUri, TC);
                    var clientCredential     = new ClientCredential(clientId, clientSecret);
                    AuthenticationResult AR  = AC.AcquireTokenByRefreshToken(refreshToken, clientCredential);

                    accessCode = AR.AccessToken;

                    // store the new refresh token
                    var refreshTokenAttribute = biAccountValue.Attributes
                                                .Where(a => a.Value.Key == "RefreshToken")
                                                .Select(a => a.Value)
                                                .FirstOrDefault();

                    Helper.SaveAttributeValue(biAccountValue, refreshTokenAttribute, AR.RefreshToken, new Rock.Data.RockContext());
                }
                catch (Exception ex)
                {
                    message = ex.Message;
                }
            }
            else
            {
                message = "Could not find saved BI account.";
            }

            return(accessCode);
        }
        protected string GetAccessToken(string tokenIdCookieName,
                                        string cookieProtectionApp,
                                        string tokenProtectionApp,
                                        string adfsAuthUserId,
                                        bool verbose,
                                        StringBuilder msg)
        {
            string refreshToken = RefreshToken(tokenIdCookieName, cookieProtectionApp, tokenProtectionApp);

            if (!string.IsNullOrWhiteSpace(refreshToken))
            {
                var ctx      = new AuthenticationContext(Startup.Config.ADFS_URL_adfs, false);
                var cred     = new ClientCredential(adfsAuthUserId, "NotASecret");
                var response = ctx.AcquireTokenByRefreshToken(refreshToken, cred);
                if (response == null)
                {
                    msg.AppendLine("no response to token from refresh token request.");
                }
                else if (string.IsNullOrWhiteSpace(response.AccessToken))
                {
                    msg.AppendLine("no access token from refresh token request.");
                }
                else
                {
                    if (verbose)
                    {
                        msg.AppendFormat("Got access token from refresh token.{0}... len = {1}, start = \"{2}\"{0}",
                                         Environment.NewLine,
                                         response.AccessToken.Length,
                                         response.AccessToken.Substring(0, 20));
                    }
                    return(response.AccessToken);
                }
            }
            else
            {
                ViewBag.Message = "No Refresh Token";
            }
            return(null);
        }
Beispiel #17
0
        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
            {
                ClientId              = clientId,
                Authority             = Authority,
                PostLogoutRedirectUri = postLogoutRedirectUri,

                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    //
                    // If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
                    //

                    AuthorizationCodeReceived = (context) =>
                    {
                        var code = context.Code;

                        if (certName.Length != 0)
                        {
                            // Create a Client Credential Using a Certificate
                            //
                            // Initialize the Certificate Credential to be used by ADAL.
                            // First find the matching certificate in the cert store.
                            //

                            X509Certificate2 cert = null;
                            X509Store store       = new X509Store(StoreLocation.CurrentUser);
                            try
                            {
                                store.Open(OpenFlags.ReadOnly);
                                // Place all certificates in an X509Certificate2Collection object.
                                X509Certificate2Collection certCollection = store.Certificates;
                                // Find unexpired certificates.
                                X509Certificate2Collection currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
                                // From the collection of unexpired certificates, find the ones with the correct name.
                                X509Certificate2Collection signingCert = currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, certName, false);
                                if (signingCert.Count == 0)
                                {
                                    // No matching certificate found.
                                    return(Task.FromResult(0));
                                }
                                // Return the first certificate in the collection, has the right name and is current.
                                cert = signingCert[0];
                            }
                            finally
                            {
                                store.Close();
                            }

                            // Then create the certificate credential.
                            ClientAssertionCertificate credential = new ClientAssertionCertificate(clientId, cert);

                            string userObjectID = context.AuthenticationTicket.Identity.FindFirst(
                                "http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
                            AuthenticationContext authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectID));
                            AuthenticationResult result       = authContext.AcquireTokenByAuthorizationCode(
                                code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId);
                            AuthenticationHelper.token = result.AccessToken;
                        }
                        else
                        {
                            // Create a Client Credential Using an Application Key
                            ClientCredential credential = new ClientCredential(clientId, appKey);
                            string userObjectID         = context.AuthenticationTicket.Identity.FindFirst(
                                "http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
                            AuthenticationContext authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectID));
                            Uri uri = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path));
                            AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
                                code, uri, credential, graphResourceId);

                            result = authContext.AcquireTokenByRefreshToken(result.RefreshToken, credential);
                            AuthenticationHelper.token = result.AccessToken;
                        }

                        return(Task.FromResult(0));
                    }
                }
            });
        }
Beispiel #18
0
        // GET: UserProfile
        public ActionResult Index()
        {
            string clientId        = ConfigurationManager.AppSettings["ida:ClientID"];
            string appKey          = ConfigurationManager.AppSettings["ida:Password"];
            string graphResourceID = "https://graph.windows.net";
            string signedInUserID  = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
            string tenantID        = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
            string userObjectID    = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;

            bool validTokenPresent = true;

            TodoListWebApp.Models.TokenCacheEntry tce = null;
            //get a token using the cached values
            var existing = db.TokenCache.FirstOrDefault(a => (a.SignedInUser == signedInUserID) && (a.ResourceID == graphResourceID));

            if (existing != null) //we have a token cache entry
            {
                tce = existing;
                //if the access token is expired
                if (tce.Expiration.DateTime < DateTime.Now)
                {
                    //use the refresh token to get a fresh set of tokens
                    try
                    {
                        ClientCredential      clientcred           = new ClientCredential(clientId, appKey);
                        AuthenticationContext authContext          = new AuthenticationContext(string.Format("https://login.windows.net/{0}", tenantID));
                        AuthenticationResult  result               = authContext.AcquireTokenByRefreshToken(tce.RefreshToken, clientId, clientcred, graphResourceID);
                        TodoListWebApp.Models.TokenCacheEntry tce2 = new TodoListWebApp.Models.TokenCacheEntry
                        {
                            SignedInUser       = signedInUserID,
                            TokenRequestorUser = result.UserInfo.UserId,
                            ResourceID         = graphResourceID,
                            AccessToken        = result.AccessToken,
                            RefreshToken       = result.RefreshToken,
                            Expiration         = result.ExpiresOn.AddMinutes(-5)
                        };
                        db.TokenCache.Remove(tce);
                        db.TokenCache.Add(tce2);
                        db.SaveChanges();
                        tce = tce2;
                    }
                    catch
                    {
                        // the refresh token might be expired
                        tce = null;
                    }
                }
            }
            else            // we don't have a cached token
            {
                tce = null; // it's already null, but for good measure...
            }

            if (tce != null)
            {
                // CallContext currentCallContext = new CallContext { AccessToken = tce.AccessToken, ClientRequestId = Guid.NewGuid(), TenantId = tenantID, ApiVersion = "2013-11-08" };

                CallContext currentCallContext = new CallContext(tce.AccessToken, Guid.NewGuid(), "2013-11-08");

                GraphConnection graphConnection = new GraphConnection(currentCallContext);
                User            user            = graphConnection.Get <User>(userObjectID);
                return(View(user));
            }
            else
            {
                ViewBag.ErrorMessage = "AuthorizationRequired";
                return(View());
            }
        }
Beispiel #19
0
        static void Main()
        {
            // get OAuth token using Client Credentials
            string tenantName = "GraphDir1.onMicrosoft.com";
            string authString = "https://login.windows.net/" + tenantName;

            AuthenticationContext authenticationContext = new AuthenticationContext(authString, false);

            // Config for OAuth client credentials
            string           clientId     = "118473c2-7619-46e3-a8e4-6da8d5f56e12";
            string           clientSecret = "hOrJ0r0TZ4GQ3obp+vk3FZ7JBVP+TX353kNo6QwNq7Q=";
            ClientCredential clientCred   = new ClientCredential(clientId, clientSecret);
            string           resource     = "https://graph.windows.net";
            string           token;

            try
            {
                AuthenticationResult authenticationResult = authenticationContext.AcquireToken(resource, clientCred);
                token = authenticationResult.AccessToken;
            }

            catch (AuthenticationException ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Acquiring a token failed with the following error: {0}", ex.Message);
                if (ex.InnerException != null)
                {
                    //You should implement retry and back-off logic per the guidance given here:http://msdn.microsoft.com/en-us/library/dn168916.aspx
                    //InnerException Message will contain the HTTP error status codes mentioned in the link above
                    Console.WriteLine("Error detail: {0}", ex.InnerException.Message);
                }
                Console.ResetColor();
                Console.ReadKey();
                return;
            }


            // record start DateTime of execution
            string CurrentDateTime = DateTime.Now.ToUniversalTime().ToString();

            //*********************************************************************
            // setup Graph connection
            //*********************************************************************
            Guid          ClientRequestId = Guid.NewGuid();
            GraphSettings graphSettings   = new GraphSettings();

            graphSettings.ApiVersion      = "2013-11-08";
            graphSettings.GraphDomainName = "graph.windows.net";
            GraphConnection graphConnection = new GraphConnection(token, ClientRequestId, graphSettings);
            VerifiedDomain  initialDomain   = new VerifiedDomain();
            VerifiedDomain  defaultDomain   = new VerifiedDomain();

            //*********************************************************************
            // Get Tenant Details
            // Note: update the string tenantId with your TenantId.
            // This can be retrieved from the login Federation Metadata end point:
            // https://login.windows.net/GraphDir1.onmicrosoft.com/FederationMetadata/2007-06/FederationMetadata.xml
            //  Replace "GraphDir1.onMicrosoft.com" with any domain owned by your organization
            // The returned value from the first xml node "EntityDescriptor", will have a STS URL
            // containing your tenantId e.g. "https://sts.windows.net/4fd2b2f2-ea27-4fe5-a8f3-7b1a7c975f34/" is returned for GraphDir1.onMicrosoft.com
            //*********************************************************************
            string      tenantId = "4fd2b2f2-ea27-4fe5-a8f3-7b1a7c975f34";
            GraphObject tenant   = graphConnection.Get(typeof(TenantDetail), tenantId);

            if (tenant == null)
            {
                Console.WriteLine("Tenant not found");
            }
            else
            {
                TenantDetail tenantDetail = (TenantDetail)tenant;
                Console.WriteLine("Tenant Display Name: " + tenantDetail.DisplayName);

                // Get the Tenant's Verified Domains
                initialDomain = tenantDetail.VerifiedDomains.First(x => x.Initial.HasValue && x.Initial.Value);
                Console.WriteLine("Initial Domain Name: " + initialDomain.Name);
                defaultDomain = tenantDetail.VerifiedDomains.First(x => x.Default.HasValue && x.Default.Value);
                Console.WriteLine("Default Domain Name: " + defaultDomain.Name);
                foreach (string techContact in tenantDetail.TechnicalNotificationMails)
                {
                    Console.WriteLine("Tenant Tech Contact: " + techContact);
                }
            }
            //*********************************************************************
            // Demonstrate Getting a list of Users with paging (get 4 users), sort by displayName
            //*********************************************************************
            Console.WriteLine("\n Retrieving Users");

            FilterGenerator userFilter = new FilterGenerator();

            userFilter.Top             = 4;
            userFilter.OrderByProperty = GraphProperty.DisplayName;
            PagedResults <User> users = graphConnection.List <User>(null, userFilter);

            foreach (User user in users.Results)
            {
                Console.WriteLine("UserObjectId: {0}  UPN: {1}", user.ObjectId, user.UserPrincipalName);
            }

            // if there are more users to retrieve, get the rest of the users, and specify maximum page size 999
            do
            {
                userFilter.Top = 999;
                if (users.PageToken != null)
                {
                    users = graphConnection.List <User>(users.PageToken, userFilter);
                    Console.WriteLine("\n Next page of results");
                }

                foreach (User user in users.Results)
                {
                    Console.WriteLine("DisplayName: {0}  UPN: {1}", user.DisplayName, user.UserPrincipalName);
                }
            } while (users.PageToken != null);

            // search for a single user by UPN
            string          searchString     = "adam@" + initialDomain.Name;
            FilterGenerator filter           = new FilterGenerator();
            Expression      filterExpression = ExpressionHelper.CreateEqualsExpression(typeof(User), GraphProperty.UserPrincipalName, searchString);

            filter.QueryFilter = filterExpression;


            User retrievedUser = new User();
            PagedResults <User> pagedUserResults = graphConnection.List <User>(null, filter);

            // should only find one user with the specified UPN
            if (pagedUserResults.Results.Count == 1)
            {
                retrievedUser = pagedUserResults.Results[0] as User;
            }
            else
            {
                Console.WriteLine("User not found {0}", searchString);
            }

            if (retrievedUser.UserPrincipalName != null)
            {
                Console.WriteLine("\n Found User: "******"  UPN: " + retrievedUser.UserPrincipalName);

                // get the user's Manager
                int count = 0;
                PagedResults <GraphObject> managers = graphConnection.GetLinkedObjects(retrievedUser, LinkProperty.Manager, null);
                foreach (GraphObject managerObject in managers.Results)
                {
                    if (managerObject.ODataTypeName.Contains("User"))
                    {
                        User manager = (User)managers.Results[count];
                        Console.WriteLine(" Manager: {0}  UPN: {1}", manager.DisplayName, manager.UserPrincipalName);
                    }
                    count++;
                }
                //*********************************************************************
                // get the user's Direct Reports
                //*********************************************************************
                int top = 99;
                PagedResults <GraphObject> directReportObjects = graphConnection.GetLinkedObjects(retrievedUser, LinkProperty.DirectReports, null, top);
                foreach (GraphObject graphObject in directReportObjects.Results)
                {
                    if (graphObject.ODataTypeName.Contains("User"))
                    {
                        User User = (User)graphObject;
                        Console.WriteLine(" DirectReport {0}: {1}  UPN: {2}", User.ObjectType, User.DisplayName, User.UserPrincipalName);
                    }

                    if (graphObject.ODataTypeName.Contains("Contact"))
                    {
                        Contact Contact = (Contact)graphObject;
                        Console.WriteLine(" DirectReport {0}: {1}  Mail: {2} ", Contact.ObjectType, Contact.DisplayName, Contact.Mail);
                    }
                }
                //*********************************************************************
                // get a list of Group IDs that the user is a member of
                //*********************************************************************
                Console.WriteLine("\n {0} is a member of the following Groups (IDs)", retrievedUser.DisplayName);
                bool           securityGroupsOnly   = false;
                IList <string> usersGroupMembership = graphConnection.GetMemberGroups(retrievedUser, securityGroupsOnly);
                foreach (String groupId in usersGroupMembership)
                {
                    Console.WriteLine("Member of Group ID: " + groupId);
                }


                //*********************************************************************
                // get the User's Group and Role membership, getting the complete set of objects
                //*********************************************************************
                PagedResults <GraphObject> memberOfObjects = graphConnection.GetLinkedObjects(retrievedUser, LinkProperty.MemberOf, null, top);
                foreach (GraphObject graphObject in memberOfObjects.Results)
                {
                    if (graphObject.ODataTypeName.Contains("Group"))
                    {
                        Group Group = (Group)graphObject;
                        Console.WriteLine(" Group: {0}  Description: {1}", Group.DisplayName, Group.Description);
                    }

                    if (graphObject.ODataTypeName.Contains("Role"))
                    {
                        Role Role = (Role)graphObject;
                        Console.WriteLine(" Role: {0}  Description: {1}", Role.DisplayName, Role.Description);
                    }
                }
            }
            //*********************************************************************
            // People picker
            // Search for a user using text string "ad" match against userPrincipalName, proxyAddresses, displayName, giveName, surname
            //*********************************************************************
            searchString = "ad";
            Console.WriteLine("\nSearching for any user with string {0} in UPN,ProxyAddresses,DisplayName,First or Last Name", searchString);

            FilterGenerator userMatchFilter = new FilterGenerator();

            userMatchFilter.Top = 19;
            Expression firstExpression  = ExpressionHelper.CreateStartsWithExpression(typeof(User), GraphProperty.UserPrincipalName, searchString);
            Expression secondExpression = ExpressionHelper.CreateAnyExpression(typeof(User), GraphProperty.ProxyAddresses, "smtp:" + searchString);

            userMatchFilter.QueryFilter = ExpressionHelper.JoinExpressions(firstExpression, secondExpression, ExpressionType.Or);

            Expression thirdExpression = ExpressionHelper.CreateStartsWithExpression(typeof(User), GraphProperty.DisplayName, searchString);

            userMatchFilter.QueryFilter = ExpressionHelper.JoinExpressions(userMatchFilter.QueryFilter, thirdExpression, ExpressionType.Or);

            Expression fourthExpression = ExpressionHelper.CreateStartsWithExpression(typeof(User), GraphProperty.GivenName, searchString);

            userMatchFilter.QueryFilter = ExpressionHelper.JoinExpressions(userMatchFilter.QueryFilter, fourthExpression, ExpressionType.Or);

            Expression fifthExpression = ExpressionHelper.CreateStartsWithExpression(typeof(User), GraphProperty.Surname, searchString);

            userMatchFilter.QueryFilter = ExpressionHelper.JoinExpressions(userMatchFilter.QueryFilter, fifthExpression, ExpressionType.Or);

            PagedResults <User> serachResults = graphConnection.List <User>(null, userMatchFilter);

            if (serachResults.Results.Count > 0)
            {
                foreach (User User in serachResults.Results)
                {
                    Console.WriteLine("User DisplayName: {0}  UPN: {1}", User.DisplayName, User.UserPrincipalName);
                }
            }
            else
            {
                Console.WriteLine("User not found");
            }

            //*********************************************************************
            // Search for a group using a startsWith filter (displayName property)
            //*********************************************************************
            Group retrievedGroup = new Group();

            searchString       = "Wash";
            filter.QueryFilter = ExpressionHelper.CreateStartsWithExpression(typeof(Group), GraphProperty.DisplayName, searchString);
            filter.Top         = 99;

            PagedResults <Group> pagedGroupResults = graphConnection.List <Group>(null, filter);

            if (pagedGroupResults.Results.Count > 0)
            {
                retrievedGroup = pagedGroupResults.Results[0] as Group;
            }
            else
            {
                Console.WriteLine("Group Not Found");
            }

            if (retrievedGroup.ObjectId != null)
            {
                Console.WriteLine("\n Found Group: " + retrievedGroup.DisplayName + "  " + retrievedGroup.Description);

                //*********************************************************************
                // get the groups' membership using GetAllDirectLinks -
                // Note this method retrieves ALL links in one request - please use this method with care - this
                // may return a very large number of objects
                //*********************************************************************

                GraphObject graphObj = (GraphObject)retrievedGroup;

                IList <GraphObject> members = graphConnection.GetAllDirectLinks(graphObj, LinkProperty.Members);
                if (members.Count > 0)
                {
                    Console.WriteLine(" Members:");
                    foreach (GraphObject graphObject in members)
                    {
                        if (graphObject.ODataTypeName.Contains("User"))
                        {
                            User User = (User)graphObject;
                            Console.WriteLine("User DisplayName: {0}  UPN: {1}", User.DisplayName, User.UserPrincipalName);
                        }

                        if (graphObject.ODataTypeName.Contains("Group"))
                        {
                            Group Group = (Group)graphObject;
                            Console.WriteLine("Group DisplayName: {0}", Group.DisplayName);
                        }

                        if (graphObject.ODataTypeName.Contains("Contact"))
                        {
                            Contact Contact = (Contact)graphObject;
                            Console.WriteLine("Contact DisplayName: {0}", Contact.DisplayName);
                        }
                    }
                }
            }
            //*********************************************************************
            // Search for a Role by displayName
            //*********************************************************************
            searchString       = "Company Administrator";
            filter.QueryFilter = ExpressionHelper.CreateStartsWithExpression(typeof(Role), GraphProperty.DisplayName, searchString);
            PagedResults <Role> pagedRoleResults = graphConnection.List <Role>(null, null);

            if (pagedRoleResults.Results.Count > 0)
            {
                foreach (GraphObject graphObject in pagedRoleResults.Results)
                {
                    Role role = graphObject as Role;
                    if (role.DisplayName == searchString.Trim())
                    {
                        Console.WriteLine("\n Found Role: {0} {1} {2} ", role.DisplayName, role.Description, role.ObjectId);
                    }
                }
            }
            else
            {
                Console.WriteLine("Role Not Found {0}", searchString);
            }

            //*********************************************************************
            // get the Service Principals
            //*********************************************************************
            filter.Top         = 999;
            filter.QueryFilter = null;
            PagedResults <ServicePrincipal> servicePrincipals = new PagedResults <ServicePrincipal>();

            do
            {
                servicePrincipals = graphConnection.List <ServicePrincipal>(servicePrincipals.PageToken, filter);
                if (servicePrincipals != null)
                {
                    foreach (ServicePrincipal servicePrincipal in servicePrincipals.Results)
                    {
                        Console.WriteLine("Service Principal AppId: {0}  Name: {1}", servicePrincipal.AppId, servicePrincipal.DisplayName);
                    }
                }
            } while (servicePrincipals.PageToken != null);

            //*********************************************************************
            // get the  Application objects
            //*********************************************************************
            filter.Top = 999;
            PagedResults <Application> applications = new PagedResults <Application>();

            do
            {
                applications = graphConnection.List <Application>(applications.PageToken, filter);
                if (applications != null)
                {
                    foreach (Application application in applications.Results)
                    {
                        Console.WriteLine("Application AppId: {0}  Name: {1}", application.AppId, application.DisplayName);
                    }
                }
            }while (applications.PageToken != null);

            string targetAppId = applications.Results[0].ObjectId;


            //********************************************************************************************
            //  We'll now switch to Authenticating using OAuth Authorization Code Grant
            //  which includes user Authentication/Delegation
            //*********************************************************************************************
            var    redirectUri                   = new Uri("https://localhost");
            string clientIdForUserAuthn          = "66133929-66a4-4edc-aaee-13b04b03207d";
            AuthenticationResult userAuthnResult = null;

            try
            {
                userAuthnResult = authenticationContext.AcquireToken(resource, clientIdForUserAuthn, redirectUri, PromptBehavior.Always);
                token           = userAuthnResult.AccessToken;
                Console.WriteLine("\n Welcome " + userAuthnResult.UserInfo.GivenName + " " + userAuthnResult.UserInfo.FamilyName);
            }
            catch (AuthenticationException ex)
            {
                string message = ex.Message;
                if (ex.InnerException != null)
                {
                    message += "InnerException : " + ex.InnerException.Message;
                }
                Console.WriteLine(message);
                Console.ReadKey();
                return;
            }

            // re-establish Graph connection using the new token
            graphConnection = new GraphConnection(token, ClientRequestId, graphSettings);

            //*********************************************************************************************
            // Create a new User with a temp password
            //*********************************************************************************************
            User userToBeAdded = new User();

            userToBeAdded.DisplayName              = "Sample App Demo User";
            userToBeAdded.UserPrincipalName        = "SampleAppDemoUser@" + defaultDomain.Name;
            userToBeAdded.AccountEnabled           = true;
            userToBeAdded.MailNickname             = "SampleAppDemoUser";
            userToBeAdded.PasswordProfile          = new PasswordProfile();
            userToBeAdded.PasswordProfile.Password = "******";
            userToBeAdded.PasswordProfile.ForceChangePasswordNextLogin = true;
            userToBeAdded.UsageLocation = "US";
            User newlyCreatedUser = new User();

            try
            {
                newlyCreatedUser = graphConnection.Add <User>(userToBeAdded);
                Console.WriteLine("\nNew User {0} was created", userToBeAdded.DisplayName);
            }
            catch (GraphException graphException)
            {
                Console.WriteLine("\nError creating new user {0} {1}", graphException.Code, graphException.Message);
            }

            //*********************************************************************************************
            // update the newly created user's Password, PasswordPolicies and City
            //*********************************************************************************************
            if (newlyCreatedUser.ObjectId != null)
            {
                string userObjectId = newlyCreatedUser.ObjectId;

                // update User's city and reset their User's password
                User updateUser = graphConnection.Get <User>(userObjectId);
                updateUser.City = "Seattle";
                PasswordProfile passwordProfile = new PasswordProfile();
                passwordProfile.Password = "******";
                passwordProfile.ForceChangePasswordNextLogin = false;
                updateUser.PasswordProfile  = passwordProfile;
                updateUser.PasswordPolicies = "DisablePasswordExpiration, DisableStrongPassword";
                try
                {
                    graphConnection.Update(updateUser);
                    Console.WriteLine("\nUser {0} was updated", updateUser.DisplayName);
                }
                catch (GraphException graphException)
                {
                    Console.WriteLine("\nError Updating the user {0} {1}", graphException.Code, graphException.Message);
                }


                //*********************************************************************************************
                // Add, then retrieve a thumbnailPhoto for the newly created user
                //*********************************************************************************************
                Bitmap thumbnailPhoto = new Bitmap(20, 20);
                thumbnailPhoto.SetPixel(5, 5, Color.Beige);
                thumbnailPhoto.SetPixel(5, 6, Color.Beige);
                thumbnailPhoto.SetPixel(6, 5, Color.Beige);
                thumbnailPhoto.SetPixel(6, 6, Color.Beige);

                using (MemoryStream ms = new MemoryStream())
                {
                    thumbnailPhoto.Save(ms, ImageFormat.Jpeg);
                    graphConnection.SetStreamProperty(newlyCreatedUser, GraphProperty.ThumbnailPhoto, ms, "image/jpeg");
                    //  graphConnection.SetStreamProperty(newlyCreatedUser, "thumbnailPhoto", ms, "image/jpeg");
                }

                using (Stream ms = graphConnection.GetStreamProperty(newlyCreatedUser, GraphProperty.ThumbnailPhoto, "image/jpeg"))
                {
                    Image jpegImage = Image.FromStream(ms);
                }



                //*********************************************************************************************
                // User License Assignment - assign EnterprisePack license to new user, and disable SharePoint service
                //   first get a list of Tenant's subscriptions and find the "Enterprisepack" one
                //   Enterprise Pack includes service Plans for ExchangeOnline, SharePointOnline and LyncOnline
                //   validate that Subscription is Enabled and there are enough units left to assign to users
                //*********************************************************************************************
                PagedResults <SubscribedSku> skus = graphConnection.List <SubscribedSku>(null, null);
                foreach (SubscribedSku sku in skus.Results)
                {
                    if (sku.SkuPartNumber == "ENTERPRISEPACK")
                    {
                        if ((sku.PrepaidUnits.Enabled.Value > sku.ConsumedUnits) && (sku.CapabilityStatus == "Enabled"))
                        {
                            // create addLicense object and assign the Enterprise Sku GUID to the skuId
                            //
                            AssignedLicense addLicense = new AssignedLicense();
                            addLicense.SkuId = sku.SkuId.Value;

                            // find plan id of SharePoint Service Plan
                            foreach (ServicePlanInfo servicePlan in sku.ServicePlans)
                            {
                                if (servicePlan.ServicePlanName.Contains("SHAREPOINT"))
                                {
                                    addLicense.DisabledPlans.Add(servicePlan.ServicePlanId.Value);
                                    break;
                                }
                            }

                            IList <AssignedLicense> licensesToAdd    = new AssignedLicense[] { addLicense };
                            IList <Guid>            licensesToRemove = new Guid[] { };

                            // attempt to assign the license object to the new user
                            try
                            {
                                graphConnection.AssignLicense(newlyCreatedUser, licensesToAdd, licensesToRemove);
                                Console.WriteLine("\n User {0} was assigned license {1}", newlyCreatedUser.DisplayName, addLicense.SkuId);
                            }
                            catch (GraphException graphException)
                            {
                                Console.WriteLine("\nLicense assingment failed {0} {1}", graphException.Code, graphException.Message);
                            }
                        }
                    }
                }

                //*********************************************************************************************
                // Add User to the "WA" Group
                //*********************************************************************************************
                if (retrievedGroup.ObjectId != null)
                {
                    try
                    {
                        graphConnection.AddLink(retrievedGroup, newlyCreatedUser, LinkProperty.Members);
                        Console.WriteLine("\nUser {0} was added to Group {1}", newlyCreatedUser.DisplayName, retrievedGroup.DisplayName);
                    }
                    catch (GraphException graphException)
                    {
                        Console.WriteLine("\nAdding user to group failed {0} {1}", graphException.Code, graphException.Message);
                    }
                }

                //*********************************************************************************************
                // Create a new Group
                //*********************************************************************************************
                Group CaliforniaEmployees = new Group();
                CaliforniaEmployees.DisplayName     = "California Employees";
                CaliforniaEmployees.Description     = "Employees in the state of California";
                CaliforniaEmployees.MailNickname    = "CalEmployees";
                CaliforniaEmployees.MailEnabled     = false;
                CaliforniaEmployees.SecurityEnabled = true;
                Group newGroup = null;
                try
                {
                    newGroup = graphConnection.Add <Group>(CaliforniaEmployees);
                    Console.WriteLine("\nNew Group {0} was created", newGroup.DisplayName);
                }
                catch (GraphException graphException)
                {
                    Console.WriteLine("\nError creating new Group {0} {1}", graphException.Code, graphException.Message);
                }

                //*********************************************************************************************
                // Add the new User member to the new Group
                //*********************************************************************************************
                if (newGroup.ObjectId != null)
                {
                    try
                    {
                        graphConnection.AddLink(newGroup, newlyCreatedUser, LinkProperty.Members);
                        Console.WriteLine("\nUser {0} was added to Group {1}", newlyCreatedUser.DisplayName, newGroup.DisplayName);
                    }
                    catch (GraphException graphException)
                    {
                        Console.WriteLine("\nAdding user to group failed {0} {1}", graphException.Code, graphException.Message);
                    }
                }


                //*********************************************************************************************
                // Delete the user that we just created
                //*********************************************************************************************
                if (newlyCreatedUser.ObjectId != null)
                {
                    try
                    {
                        graphConnection.Delete(newlyCreatedUser);
                        Console.WriteLine("\nUser {0} was deleted", newlyCreatedUser.DisplayName);
                    }
                    catch (GraphException graphException)
                    {
                        Console.WriteLine("Deleting User failed {0} {1}", graphException.Code, graphException.Message);
                    }
                }

                //*********************************************************************************************
                // Delete the Group that we just created
                //*********************************************************************************************
                if (newGroup.ObjectId != null)
                {
                    try
                    {
                        graphConnection.Delete(newGroup);
                        Console.WriteLine("\nGroup {0} was deleted", newGroup.DisplayName);
                    }
                    catch (GraphException graphException)
                    {
                        Console.WriteLine("Deleting Group failed: {0} {1}", graphException.Code, graphException.Message);
                    }
                }
            }

            //*********************************************************************************************
            // Get a list of Mobile Devices from tenant
            //*********************************************************************************************
            Console.WriteLine("\nGetting Devices");
            FilterGenerator deviceFilter = new FilterGenerator();

            deviceFilter.Top = 999;
            PagedResults <Device> devices = graphConnection.List <Device>(null, deviceFilter);

            foreach (Device device in devices.Results)
            {
                if (device.ObjectId != null)
                {
                    Console.WriteLine("Device ID: {0}, Type: {1}", device.DeviceId, device.DeviceOSType);
                    foreach (GraphObject owner in device.RegisteredOwners)
                    {
                        Console.WriteLine("Device Owner ID: " + owner.ObjectId);
                    }
                }
            }

            //*********************************************************************************************
            // Create a new Application object
            //*********************************************************************************************
            Application appObject = new Application();

            appObject.DisplayName = "Test-Demo App";
            appObject.IdentifierUris.Add("https://localhost/demo/" + Guid.NewGuid().ToString());
            appObject.ReplyUrls.Add("https://localhost/demo");

            // created Keycredential object for the new App object
            KeyCredential KeyCredential = new KeyCredential();

            KeyCredential.StartDate = DateTime.UtcNow;
            KeyCredential.EndDate   = DateTime.UtcNow.AddYears(1);
            KeyCredential.Type      = "Symmetric";
            KeyCredential.Value     = Convert.FromBase64String("g/TMLuxgzurjQ0Sal9wFEzpaX/sI0vBP3IBUE/H/NS4=");
            KeyCredential.Usage     = "Verify";
            appObject.KeyCredentials.Add(KeyCredential);

            GraphObject newApp = null;

            try
            {
                newApp = graphConnection.Add(appObject);
                Console.WriteLine("New Application created: " + newApp.ObjectId);
            }
            catch (GraphException graphException)
            {
                Console.WriteLine("Application Creation execption: {0} {1}", graphException.Code, graphException.Message);
            }

            // Get the application object that was just created
            if (newApp != null)
            {
                GraphObject app          = graphConnection.Get(typeof(Application), newApp.ObjectId);
                Application retrievedApp = (Application)app;

                //*********************************************************************************************
                // create a new Service principal
                //*********************************************************************************************
                ServicePrincipal newServicePrincpal = new ServicePrincipal();
                newServicePrincpal.DisplayName    = "Test-Demo App";
                newServicePrincpal.AccountEnabled = true;
                newServicePrincpal.AppId          = retrievedApp.AppId;

                GraphObject newSP = null;
                try
                {
                    newSP = graphConnection.Add <ServicePrincipal>(newServicePrincpal);
                    //    newSP = graphConnection.Add(newServicePrincpal);
                    Console.WriteLine("New Service Principal created: " + newSP.ObjectId);
                }
                catch (GraphException graphException)
                {
                    Console.WriteLine("Service Principal Creation execption: {0} {1}", graphException.Code, graphException.Message);
                }


                //*********************************************************************************************
                // get all Permission Objects
                //*********************************************************************************************
                Console.WriteLine("\n Getting Permissions");
                filter.Top = 999;
                PagedResults <Permission> permissions = new PagedResults <Permission>();
                do
                {
                    try
                    {
                        permissions = graphConnection.List <Permission>(permissions.PageToken, filter);
                    }
                    catch (GraphException graphException)
                    {
                        Console.WriteLine("Error: {0} {1}", graphException.Code, graphException.Message);
                        break;
                    }

                    foreach (Permission permission in permissions.Results)
                    {
                        Console.WriteLine("Permission: {0}  Name: {1}", permission.ClientId, permission.Scope);
                    }
                } while (permissions.PageToken != null);

                //*********************************************************************************************
                // Create new permission object
                //*********************************************************************************************
                Permission permissionObject = new Permission();
                permissionObject.ConsentType = "AllPrincipals";
                permissionObject.Scope       = "user_impersonation";
                permissionObject.StartTime   = DateTime.Now;
                permissionObject.ExpiryTime  = (DateTime.Now).AddMonths(12);

                // resourceId is objectId of the resource, in this case objectId of AzureAd (Graph API)
                permissionObject.ResourceId = "dbf73c3e-e80b-495b-a82f-2f772bb0a417";

                //ClientId = objectId of servicePrincipal
                permissionObject.ClientId = newSP.ObjectId;

                GraphObject newPermission = null;
                try
                {
                    newPermission = graphConnection.Add(permissionObject);
                    Console.WriteLine("New Permission object created: " + newPermission.ObjectId);
                }
                catch (GraphException graphException)
                {
                    Console.WriteLine("Permission Creation exception: {0} {1}", graphException.Code, graphException.Message);
                }

                //*********************************************************************************************
                // Delete Application Objects
                //*********************************************************************************************

                if (retrievedApp.ObjectId != null)
                {
                    try
                    {
                        graphConnection.Delete(retrievedApp);
                        Console.WriteLine("Deleting Application object: " + retrievedApp.ObjectId);
                    }
                    catch (GraphException graphException)
                    {
                        Console.WriteLine("Application Deletion execption: {0} {1}", graphException.Code, graphException.Message);
                    }
                }
            }

            //*********************************************************************************************
            // Show Batching with 3 operators.  Note: up to 5 operations can be in a batch
            //*********************************************************************************************
            // get users
            Console.WriteLine("\n Executing Batch Request");
            BatchRequestItem firstItem = new BatchRequestItem(
                "GET",
                false,
                Utils.GetListUri <User>(graphConnection, null, new FilterGenerator()),
                null,
                String.Empty);

            // get members of a Group
            Uri membersUri = Utils.GetRequestUri <Group>(graphConnection, retrievedGroup.ObjectId, "members");

            BatchRequestItem secondItem = new BatchRequestItem(
                "GET",
                false,
                new Uri(membersUri.ToString()),
                null,
                String.Empty);

            // update an existing group's Description property

            retrievedGroup.Description = "New Employees in Washington State";

            BatchRequestItem thirdItem = new BatchRequestItem(
                "Patch",
                true,
                Utils.GetRequestUri <Group>(graphConnection, retrievedGroup.ObjectId),
                null,
                retrievedGroup.ToJson(true));

            // Execute the batch requst
            IList <BatchRequestItem>  batchRequest   = new BatchRequestItem[] { firstItem, secondItem, thirdItem };
            IList <BatchResponseItem> batchResponses = graphConnection.ExecuteBatch(batchRequest);

            int responseCount = 0;

            foreach (BatchResponseItem responseItem in batchResponses)
            {
                if (responseItem.Failed)
                {
                    Console.WriteLine("Failed: {0} {1}",
                                      responseItem.Exception.Code,
                                      responseItem.Exception.ErrorMessage);
                }
                else
                {
                    Console.WriteLine("Batch Item Result {0} succeeded {1}",
                                      responseCount++,
                                      !responseItem.Failed);
                }
            }

            // this next section shows how to access the signed-in user's mailbox.
            // First we get a new token for Office365 Exchange Online Resource
            // using the multi-resource refresh token tha was included when the previoius
            // token was acquired.
            // We can now request a new token for Office365 Exchange Online.
            //
            string office365Emailresource = "https://outlook.office365.com/";
            string office365Token         = null;

            if (userAuthnResult.IsMultipleResourceRefreshToken)
            {
                userAuthnResult = authenticationContext.AcquireTokenByRefreshToken(userAuthnResult.RefreshToken, clientIdForUserAuthn, office365Emailresource);
                office365Token  = userAuthnResult.AccessToken;

                //
                // Call the Office365 API and retrieve the top item from the user's mailbox.
                //
                string     requestUrl = "https://outlook.office365.com/EWS/OData/Me/Inbox/Messages?$top=1";
                WebRequest getMailboxRequest;
                getMailboxRequest = WebRequest.Create(requestUrl);
                getMailboxRequest.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + office365Token);
                Console.WriteLine("\n Getting the User's Mailbox Contents \n");

                //
                // Read the contents of the user's mailbox, and display to the console.
                //
                Stream objStream = null;
                try
                {
                    objStream = getMailboxRequest.GetResponse().GetResponseStream();
                    StreamReader objReader = new StreamReader(objStream);

                    string sLine = "";
                    int    i     = 0;

                    while (sLine != null)
                    {
                        i++;
                        sLine = objReader.ReadLine();
                        if (sLine != null)
                        {
                            Console.WriteLine("{0}:{1}", i, sLine);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("\n Error Getting User's Mailbox: {0} \n", ex.Message);
                }
            }

            //*********************************************************************************************
            // End of Demo Console App
            //*********************************************************************************************
            Console.WriteLine("\nCompleted at {0} \n ClientRequestId: {1}", CurrentDateTime, ClientRequestId);
            Console.ReadKey();
            return;
        }