public async Task<bool> AuthenticationByExternalBrowser(CloudDriveScopes scope, TimeSpan timeout, CancellationToken? cancelToken = null, string unformatedRedirectUrl = "http://localhost:{0}/signin/", Func<int, int, int> portSelector = null)
{
string redirectUrl;
using (var redirectListener = CreateListener(unformatedRedirectUrl, out redirectUrl, portSelector))
{
redirectListener.Start();
var loginurl = BuildLoginUrl(redirectUrl, scope);
using (var tabProcess = Process.Start(redirectUrl))
{
for (var times = 0; times < 2; times++)
{
var task = redirectListener.GetContextAsync();
var timeoutTask = (cancelToken != null) ? Task.Delay(timeout, cancelToken.Value) : Task.Delay(timeout);
var anytask = await Task.WhenAny(task, timeoutTask).ConfigureAwait(false);
if (anytask == task)
{
var context = await task.ConfigureAwait(false);
if (times == 0)
{
var loginResponse = Encoding.UTF8.GetBytes(string.Format(DefaultOpenAuthResponse, loginurl));
await SendResponse(context.Response, loginResponse).ConfigureAwait(false);
}
else
{
await ProcessRedirect(context, redirectUrl).ConfigureAwait(false);
}
}
else
{
if (timeoutTask.IsCanceled)
{
return false;
}
throw new TimeoutException("No redirection detected");
}
}
}
}
return token != null;
}