OneDrive / onedrive-sdk-dotnet-msa-auth-adapter

Other
26 stars 22 forks source link

Will there be updates to use later versions of Microsoft.IdentityModel.Clients.ActiveDirectory? #66

Closed ThomasBarnekow closed 3 years ago

ThomasBarnekow commented 6 years ago

Thanks for providing this library! It has been very helpful. However, it has been preventing me from upgrading to the newer versions of Microsoft.IdentityModel.Clients.ActiveDirectory for quite some time now.

I understand that the v3 versions introduce breaking changes, which will also lead to breaking changes in this library. But I would be interested to hear about any future upgrade plans.

ThomasBarnekow commented 6 years ago

For anybody who's interested, I have created a simple IAuthenticationProvider implementation, using the latest Microsoft.IdentityModel.Clients.ActiveDirectory (3.19.6). There is obviously not a lot of error checking etc., but it demonstrates how easy it can be for specific use cases.

public interface IAdalAuthenticationProvider : IAuthenticationProvider
{
    Task<AuthenticationResult> AuthenticateUserAsync(
        [NotNull] string resource,
        PromptBehavior promptBehavior = PromptBehavior.SelectAccount);
}

public class AdalAuthenticationProvider : IAdalAuthenticationProvider
{
    private readonly string _clientId;
    private readonly Uri _redirectUri;
    private readonly AuthenticationContext _authenticationContext;

    private string _resource;

    public AdalAuthenticationProvider(
        [NotNull] string clientId,
        [NotNull] string redirectUri,
        [NotNull] AuthenticationContext authenticationContext) : this(clientId, new Uri(redirectUri), authenticationContext)
    {
    }

    public AdalAuthenticationProvider(
        [NotNull] string clientId,
        [NotNull] Uri redirectUri,
        [NotNull] AuthenticationContext authenticationContext)
    {
        _clientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
        _redirectUri = redirectUri ?? throw new ArgumentNullException(nameof(redirectUri));
        _authenticationContext = authenticationContext ?? throw new ArgumentNullException(nameof(authenticationContext));
    }

    /// <inheritdoc />
    public async Task AuthenticateRequestAsync(HttpRequestMessage request)
    {
        AuthenticationResult authenticationResult = await AcquireTokenAsync().ConfigureAwait(false);

        request.Headers.Authorization = new AuthenticationHeaderValue(
            authenticationResult.AccessTokenType ?? "Bearer",
            authenticationResult.AccessToken);
    }

    /// <inheritdoc />
    public async Task<AuthenticationResult> AuthenticateUserAsync(
        string resource,
        PromptBehavior promptBehavior = PromptBehavior.SelectAccount)
    {
        _resource = resource ?? throw new ArgumentNullException(nameof(resource));

        return await AcquireTokenAsync(promptBehavior);
    }

    private async Task<AuthenticationResult> AcquireTokenAsync(PromptBehavior promptBehavior = PromptBehavior.SelectAccount)
    {
        if (_resource == null) throw new InvalidOperationException("User not authenticated.");

        try
        {
            return await _authenticationContext
                .AcquireTokenSilentAsync(_resource, _clientId)
                .ConfigureAwait(false);
        }
        catch (Exception)
        {
            return await _authenticationContext
                .AcquireTokenAsync(_resource, _clientId, _redirectUri, new PlatformParameters(promptBehavior))
                .ConfigureAwait(false);
        }
    }
}