Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new provoder for Daemon type apps. #25

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// ------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All Rights Reserved.
// Licensed under the MIT License.
// See License in the project root for license information.
// ------------------------------------------------------------------------------
using System;
using System.Threading.Tasks;
using Microsoft.Graph;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Globalization;
using System.Threading;

namespace Microsoft.OneDrive.Sdk.Authentication.Business
{
public class AdalDaemonAuthenticationProvider : AdalAuthenticationProviderBase
{
private const int _retryCount = 3;
private const int _retrySleepDuration = 3000;
protected string _clientId;
protected string _clientKey;

public IAuthenticationContextWrapper authContextWrapper;
protected ClientCredential clientCredential;

protected override AuthenticateUserDelegate AuthenticateUser { get; set; }
protected override AuthenticateUserSilentlyDelegate AuthenticateUserSilently { get; set; }

/// <summary>
/// Authenticates the user silently
/// </summary>
/// <param name="clientId">Your Application ID</param>
/// <param name="clientSecret">Your Application Key</param>
/// <param name="tenant">is usually a domain name for your Office365 service. Like 'yourcompany.onmicrosoft.com'</param>
public AdalDaemonAuthenticationProvider(
string clientId,
string returnUrl,
string clientSecret,
string tenant,
IAuthenticationContextWrapper authenticationContextWrapper) : base(clientId, returnUrl, authenticationContextWrapper)
{
_clientId = clientId;
_clientKey = clientSecret;

string authority = String.Format(CultureInfo.InvariantCulture, "https://login.microsoftonline.com/{0}", tenant);
this.authContextWrapper = authenticationContextWrapper;
this.clientCredential = new ClientCredential(_clientId, _clientKey);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.clientCredential = new ClientCredential(this._clientId, this._clientKey);

Please look for this everywhere in the file. Instance members and methods should always have this.


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only 1 extra line

this.AuthenticateUser = this.PromptUserForAuthenticationAsync;
this.AuthenticateUserSilently = this.SilentlyAuthenticateUserAsync;
}

public async Task AuthenticateUserAsync(string serviceResourceId)
{
IAuthenticationResult result = null;
result = null;
int retryCount = 0;
bool retry = false;
currentServiceResourceId = serviceResourceId;
do
{
retry = false;
try
{
result = await this.authContextWrapper.AcquireTokenSilentAsync(
serviceResourceId,
clientCredential);
}
catch (AdalException ex)
{
if (ex.ErrorCode == "temporarily_unavailable")
{
retry = true;
retryCount++;
await Task.Delay(_retrySleepDuration);
}
}

} while ((retry == true) && (retryCount < _retryCount));

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra whitespace

this.CurrentAccountSession = this.ConvertAuthenticationResultToAccountSession(result);
}

public override Task AuthenticateUserWithRefreshTokenAsync(string refreshToken)
{
return this.AuthenticateUserWithRefreshTokenAsync(refreshToken, /* serviceResourceId */ null);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra whitespace

public override async Task AuthenticateUserWithRefreshTokenAsync(string refreshToken, string serviceResourceId)
{
// Daemon App doesn't have refresh token.
// So we do the authentication again.
await this.AuthenticateUserAsync(this.currentServiceResourceId);
}

private async Task<IAuthenticationResult> SilentlyAuthenticateUserAsync(
string serviceResourceId,
string userId,
bool throwOnError)
{
var result = await this.authContextWrapper.AcquireTokenSilentAsync(
serviceResourceId,
clientCredential);
return result;
}

private Task<IAuthenticationResult> PromptUserForAuthenticationAsync(string serviceResourceId, string userId)
{
return this.SilentlyAuthenticateUserAsync(
serviceResourceId,
userId,
true);
}
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ public ITokenCache TokenCache
}
}


/// <summary>
/// Authenticates the daemon app silently"/>.
/// </summary>
/// <param name="resource">The resource to authenticate against.</param>
/// <param name="clientCredential">The client credential of the application.</param>
/// <returns>The <see cref="IAuthenticationResult"/>.</returns>
public async Task<IAuthenticationResult> AcquireTokenSilentAsync(string resource, ClientCredential clientCredential)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yikes sorry, this should actually be AcquireTokenAsync. It should match the call to AuthenticationContext to make it a little easier for the client to figure out what's happening under the covers. Sorry if I gave you the wrong name before :(

{
var result = await this.authenticationContext.AcquireTokenAsync(resource, clientCredential).ConfigureAwait(false);
return result == null ? null : new AuthenticationResultWrapper(result);
}

/// <summary>
/// Authenticates the user silently using <see cref="AuthenticationContext.AcquireTokenSilentAsync(string, string, UserIdentifier)"/>.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ public interface IAuthenticationContextWrapper
{
ITokenCache TokenCache { get; }

/// <summary>
/// Authenticates the daemon app silently"/>.
/// </summary>
/// <param name="resource">The resource to authenticate against.</param>
/// <param name="clientCredential">The client credential of the application.</param>
/// <returns>The <see cref="IAuthenticationResult"/>.</returns>
Task<IAuthenticationResult> AcquireTokenSilentAsync(string resource, ClientCredential clientCredential);

/// <summary>
/// Authenticates the user silently using <see cref="AuthenticationContext.AcquireTokenSilentAsync(string, string, UserIdentifier)"/>.
/// </summary>
Expand Down
Loading