I want to authenticate to Azure Active Directory via C# and retrieve much data from SharePoint. Therefore I added parallel requests and a central authentication method. In the method I do cache the token, so I only need to request the token once.
public class AuthHelper
{
string authorityUrl = "https://login.microsoftonline.com/{0}/";
public string TenantId { get; set; } = "<GUID>";
public string ClientId { get; set; } = "<GUID>";
public string Username { get; set; } = "MyUsername";
public string UserPW { get; set; } = "MyPa$$w0rd!";
public string HostURL { get; set; } = "http://contoso.sharepoint.com/...";
private string tmpToken;
public string GetJWTToken()
{
// get new Token from service
if (IsTokenExpired(tmpToken))
{
var scopes = new List<string>();
// parse uri, to use hostname like 'contoso.sharepoint.com' with the default rights
var uri = new Uri(HostURL);
var resource = uri.Scheme + Uri.SchemeDelimiter + uri.Host + "/.default";
scopes.Add(resource);
IPublicClientApplication app = PublicClientApplicationBuilder.Create(ClientId)
.WithAuthority(string.Format(authorityUrl, TenantId))
.WithTenantId(TenantId)
.Build();
var securePassword = new SecureString();
foreach (char c in UserPW) securePassword.AppendChar(c);
// following line throw the exception
var result = app.AcquireTokenByUsernamePassword(scopes, Username, securePassword).ExecuteAsync().Result;
tmpToken = result.AccessToken;
}
return tmpToken;
}
public bool IsTokenExpired(string token)
{
if (token == null)
return true;
// check if tmpToken is still valid
else
{
var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler();
var tokenDecoded = handler.ReadJwtToken(token);
if (tokenDecoded.ValidTo < DateTime.UtcNow)
return true;
}
return false;
}
}
When requesting multiple resources in parallel from SharePoint I get the following exception:
AADSTS50196: The server terminated an operation because it encountered a client request loop. Please contact your app vendor. Trace ID: <GUID> Correlation ID: <GUID> Timestamp: ...