CSharp/SPO.Samples/SPO.ModernAuthentication/Helpers/UserAuthenticationManager.cs
/// <summary>
/// Method to Ensure Access Token Async.
/// </summary>
/// <param name="resourceUri">Resource Uri.</param>
/// <param name="userPrincipalName">UPN.</param>
/// <param name="userPassword">UserName.</param>
/// <param name="clientId">AAD App Client Id.</param>
/// <returns>Access Token.</returns>
Method to Ensure Access Token Async.
Method to Ensure Access Token Async .
public async Task<string> EnsureAccessTokenAsync(Uri resourceUri, string userPrincipalName, string userPassword, string clientId)
        {
            string accessTokenFromCache = TokenFromCache(resourceUri, this.tokenCache);
            if (accessTokenFromCache == null)
            {
                await SemaphoreSlimTokens.WaitAsync().ConfigureAwait(false);
                try
                {
                    string accessToken = await this.AcquireTokenAsync(resourceUri, userPrincipalName, userPassword, clientId).ConfigureAwait(false);
                    Console.WriteLine($"Successfully requested new access token resource {resourceUri.DnsSafeHost} for user {userPrincipalName}");
                    AddTokenToCache(resourceUri, this.tokenCache, accessToken);
                    this.tokenResetEvent = new AutoResetEvent(false);
                    TokenWaitInfo wi = new TokenWaitInfo();
                    wi.Handle = ThreadPool.RegisterWaitForSingleObject(
                        this.tokenResetEvent,
                        async (state, timedOut) =>
                        {
                            if (!timedOut)
                            {
                                TokenWaitInfo internalWaitToken = (TokenWaitInfo)state;
                                if (internalWaitToken.Handle != null)
                                {
                                    internalWaitToken.Handle.Unregister(null);
                                }
                            }
                            else
                            {
                                try
                                {
                                    await SemaphoreSlimTokens.WaitAsync().ConfigureAwait(false);
                                    RemoveTokenFromCache(resourceUri, this.tokenCache);
                                    Console.WriteLine($"Cached token for resource {resourceUri.DnsSafeHost} and user {userPrincipalName} expired");
                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine($"Something went wrong during cache token invalidation: {ex.Message}");
                                    RemoveTokenFromCache(resourceUri, this.tokenCache);
                                }
                                finally
                                {
                                    SemaphoreSlimTokens.Release();
                                }
                            }
                        },
                        wi,
                        (uint)CalculateThreadSleep(accessToken).TotalMilliseconds,
                        true);
                    return accessToken;
                }
                finally
                {
                    SemaphoreSlimTokens.Release();
                }
            }
            else
            {
                Console.WriteLine($"Returning token from cache for resource {resourceUri.DnsSafeHost} and user {userPrincipalName}");
                return accessTokenFromCache;
            }
        }
public async Task < string > EnsureAccessTokenAsync ( Uri resourceUri , string userPrincipalName , string userPassword , string clientId ) { string accessTokenFromCache = TokenFromCache ( resourceUri , this . tokenCache ) ; if ( accessTokenFromCache == null ) { await SemaphoreSlimTokens . WaitAsync ( ) . ConfigureAwait ( false ) ; try { string accessToken = await this . AcquireTokenAsync ( resourceUri , userPrincipalName , userPassword , clientId ) . ConfigureAwait ( false ) ; Console . WriteLine ( $" Successfully requested new access token resource  { resourceUri . DnsSafeHost }  for user  { userPrincipalName } " ) ; AddTokenToCache ( resourceUri , this . tokenCache , accessToken ) ; this . tokenResetEvent = new AutoResetEvent ( false ) ; TokenWaitInfo wi = new TokenWaitInfo ( ) ; wi . Handle = ThreadPool . RegisterWaitForSingleObject ( this . tokenResetEvent , async ( state , timedOut ) => { if ( ! timedOut ) { TokenWaitInfo internalWaitToken = ( TokenWaitInfo ) state ; if ( internalWaitToken . Handle != null ) { internalWaitToken . Handle . Unregister ( null ) ; } } else { try { await SemaphoreSlimTokens . WaitAsync ( ) . ConfigureAwait ( false ) ; RemoveTokenFromCache ( resourceUri , this . tokenCache ) ; Console . WriteLine ( $" Cached token for resource  { resourceUri . DnsSafeHost }  and user  { userPrincipalName }  expired " ) ; } catch ( Exception ex ) { Console . WriteLine ( $" Something went wrong during cache token invalidation:  { ex . Message } " ) ; RemoveTokenFromCache ( resourceUri , this . tokenCache ) ; } finally { SemaphoreSlimTokens . Release ( ) ; } } } , wi , ( uint ) CalculateThreadSleep ( accessToken ) . TotalMilliseconds , true ) ; return accessToken ; } finally { SemaphoreSlimTokens . Release ( ) ; } } else { Console . WriteLine ( $" Returning token from cache for resource  { resourceUri . DnsSafeHost }  and user  { userPrincipalName } " ) ; return accessTokenFromCache ; } }
Method to Ensure Access Token Async.
Method to Ensure Access Token Async .
// No async methods are allowed in a lock section // Register a thread to invalidate the access token once's it's expired // Take a lock to ensure no other threads are updating the SharePoint Access token at this time
None
resourceUri
Uri
None
userPrincipalName
string
None
userPassword
string
None
clientId
string
AAD App Client Id.
AAD App Client Id .