Skip to content

Commit

Permalink
Fetch new token on login to ensure new scopes are available (#274)
Browse files Browse the repository at this point in the history
* Fetch new token on login to ensure new scopes are available

* Bump version

* Apply suggestions from code review

---------

Co-authored-by: Vincent Biret <vibiret@microsoft.com>
  • Loading branch information
calebkiage and baywet authored Oct 19, 2023
1 parent 38d97d0 commit b6b5388
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,12 @@ namespace Microsoft.Graph.Cli.Core.Authentication;
/// <typeparam name="T">An app-only token credential type</typeparam>
public class AppOnlyLoginService<T> : LoginServiceBase where T : TokenCredential
{
private T credential;

/// <summary>
/// Creates a new instance of an app-only login service.
/// </summary>
/// <param name="credential">The app-only login credential.</param>
/// <param name="pathUtility">The path utility instance.</param>
public AppOnlyLoginService(T credential, IPathUtility pathUtility) : base(pathUtility)
public AppOnlyLoginService(IPathUtility pathUtility) : base(pathUtility)
{
this.credential = credential;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,17 @@ public virtual async Task<LoginServiceBase> GetAuthenticationServiceAsync(Authen
{
return new InteractiveLoginService<InteractiveBrowserCredential>(browserCred, pathUtility);
}
else if (strategy == AuthenticationStrategy.ClientCertificate && credential is ClientCertificateCredential certCred)
else if (strategy == AuthenticationStrategy.ClientCertificate && credential is ClientCertificateCredential)
{
return new AppOnlyLoginService<ClientCertificateCredential>(GetClientCertificateCredential(tenantId, clientId, certificateName, certificateThumbPrint), pathUtility);
return new AppOnlyLoginService<ClientCertificateCredential>(pathUtility);
}
else if (strategy == AuthenticationStrategy.ManagedIdentity && credential is ManagedIdentityCredential managedIdentityCred)
else if (strategy == AuthenticationStrategy.ManagedIdentity && credential is ManagedIdentityCredential)
{
return new AppOnlyLoginService<ManagedIdentityCredential>(managedIdentityCred, pathUtility);
return new AppOnlyLoginService<ManagedIdentityCredential>(pathUtility);
}
else if (strategy == AuthenticationStrategy.Environment && credential is EnvironmentCredential envCred)
else if (strategy == AuthenticationStrategy.Environment && credential is EnvironmentCredential)
{
return new AppOnlyLoginService<EnvironmentCredential>(envCred, pathUtility);
return new AppOnlyLoginService<EnvironmentCredential>(pathUtility);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,18 @@ public InteractiveLoginService(T credential, IPathUtility pathUtility) : base(pa
/// <exception cref="InvalidOperationException">When the credential is not supported.</exception>
protected override async Task<AuthenticationRecord?> DoLoginAsync(string[] scopes, CancellationToken cancellationToken = default)
{
if (credential is DeviceCodeCredential deviceCodeCred)
var requestContext = new TokenRequestContext(scopes);
var record = credential switch
{
return await deviceCodeCred.AuthenticateAsync(new TokenRequestContext(scopes), cancellationToken);
}
else if (credential is InteractiveBrowserCredential browserCred)
{
return await browserCred.AuthenticateAsync(new TokenRequestContext(scopes), cancellationToken);
}
DeviceCodeCredential deviceCodeCred => await deviceCodeCred.AuthenticateAsync(requestContext, cancellationToken).ConfigureAwait(false),
InteractiveBrowserCredential browserCred => await browserCred.AuthenticateAsync(requestContext, cancellationToken).ConfigureAwait(false),
// Due to the check in the constructor, this code shouldn't be reachable normally.
_ => throw new InvalidOperationException("The provided credential is not supported."),
};

// Request a new token to update the cache allowing incremental consent.
var _ = await credential.GetTokenAsync(requestContext, cancellationToken).ConfigureAwait(false);

// Due to the check in the constructor, this code shouldn't be reachable normally.
throw new InvalidOperationException("The provided credential is not supported.");
return record;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<!-- Recommended: Embed symbols containing Source Link in the main file (exe/dll) -->
<DebugType>embedded</DebugType>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>preview.6</VersionSuffix>
<VersionSuffix>preview.7</VersionSuffix>
</PropertyGroup>

<PropertyGroup>
Expand Down

0 comments on commit b6b5388

Please sign in to comment.