Skip to content

Commit

Permalink
Updated to use modern browser based auth
Browse files Browse the repository at this point in the history
  • Loading branch information
erwinvanhunen committed Nov 20, 2024
1 parent 40332aa commit 14c215e
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 18 deletions.
36 changes: 27 additions & 9 deletions src/lib/PnP.Framework/AuthenticationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,22 @@ public static AuthenticationManager CreateWithDeviceLogin(string clientId, strin
public static AuthenticationManager CreateWithInteractiveLogin(string clientId, Action<string, int> openBrowserCallback, string tenantId = null, string successMessageHtml = null, string failureMessageHtml = null, AzureEnvironment azureEnvironment = AzureEnvironment.Production, Action<ITokenCache> tokenCacheCallback = null, bool useWAM = false)
{
return new AuthenticationManager(clientId, Utilities.OAuth.DefaultBrowserUi.FindFreeLocalhostRedirectUri(), tenantId, azureEnvironment, tokenCacheCallback, new Utilities.OAuth.DefaultBrowserUi(openBrowserCallback, successMessageHtml, failureMessageHtml), useWAM);
}

/// <summary>
/// Creates a new instance of the Authentication Manager to acquire access tokens and client contexts using the Azure AD Interactive flow.
/// </summary>
/// <param name="clientId">The client id of the Azure AD application to use for authentication</param>
/// <param name="openBrowserCallback">This callback will be called providing the URL and port to open during the authentication flow</param>
/// <param name="tenantId">Optional tenant id or tenant url</param>
/// <param name="successFullMessageHtml">Allows you to override the success message. You will have to provide the full HTML document.</param>
/// <param name="failureFullMessageHtml">llows you to override the failure message. You will have to provide the full HTML document.</param>
/// <param name="azureEnvironment">The azure environment to use. Defaults to AzureEnvironment.Production</param>
/// <param name="tokenCacheCallback">If present, after setting up the base flow for authentication this callback will be called to register a custom tokencache. See https://aka.ms/msal-net-token-cache-serialization.</param>
/// <param name="useWAM">If true, uses WAM for authentication. Works only on Windows OS. Default is false</param>
public static AuthenticationManager CreateWithInteractiveWebBrowserLogin(string clientId, Action<string, int> openBrowserCallback, string tenantId = null, string successFullMessageHtml = null, string failureFullMessageHtml = null, AzureEnvironment azureEnvironment = AzureEnvironment.Production, Action<ITokenCache> tokenCacheCallback = null, bool useWAM = false)
{
return new AuthenticationManager(clientId, Utilities.OAuth.DefaultBrowserUi.FindFreeLocalhostRedirectUri(), tenantId, azureEnvironment, tokenCacheCallback, new Utilities.OAuth.DefaultBrowserUi(openBrowserCallback, successFullMessageHtml, failureFullMessageHtml, true), useWAM);
}

/// <summary>
Expand Down Expand Up @@ -771,8 +787,8 @@ public string GetAccessToken(string siteUrl, CancellationToken cancellationToken
/// <param name="siteUrl"></param>
/// <param name="cancellationToken">Optional cancellation token to cancel the request</param>
/// <param name="prompt">The prompt style to use. Notice that this only works with the Interactive Login flow, for all other flows this parameter is ignored.</param>
/// <param name="appName">Optional app name to show when using on MacOS
/// <param name="appUrl">Optional url of app to show when using on MacOS
/// <param name="appName">Optional app name to show when using on MacOS</param>
/// <param name="appUrl">Optional url of app to show when using on MacOS</param>
/// <returns></returns>
public string GetAccessToken(string siteUrl, CancellationToken cancellationToken, Prompt prompt = default, string appName = "PnP", string appUrl = "https://pnp.github.io")
{
Expand Down Expand Up @@ -818,8 +834,8 @@ public async Task<string> GetAccessTokenAsync(string[] scopes, Prompt prompt = d
/// <param name="cancellationToken">Optional cancellation token to cancel the request</param>
/// <param name="prompt">The prompt style to use. Notice that this only works with the Interactive Login flow, for all other flows this parameter is ignored.</param>
/// <param name="uri">for ClientContextType.PnPCoreSdk case as by interface definition needed for GetAccessTokenAsync</param>
/// <param name="appName">Optional app name to show when using on MacOS
/// <param name="appUrl">Optional url of app to show when using on MacOS
/// <param name="appName">Optional app name to show when using on MacOS</param>
/// <param name="appUrl">Optional url of app to show when using on MacOS</param>
/// <returns></returns>
public async Task<string> GetAccessTokenAsync(string[] scopes, CancellationToken cancellationToken, Prompt prompt = default, Uri uri = null, string appName = "PnP", string appUrl = "https://pnp.github.io")
{
Expand Down Expand Up @@ -856,7 +872,9 @@ public async Task<string> GetAccessTokenAsync(string[] scopes, CancellationToken
catch
{
var builder = publicClientApplication.AcquireTokenInteractive(scopes);
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))

// On MacOS we always use the browser login
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
var options = new SystemWebViewOptions()
{
Expand Down Expand Up @@ -979,8 +997,8 @@ public ClientContext GetContext(string siteUrl)
/// </summary>
/// <param name="siteUrl"></param>
/// <param name="cancellationToken">Optional cancellation token to cancel the request</param>
/// <param name="appName">Optional app name to show when using on MacOS
/// <param name="appUrl">Optional url of app to show when using on MacOS
/// <param name="appName">Optional app name to show when using on MacOS</param>
/// <param name="appUrl">Optional url of app to show when using on MacOS</param>
/// <returns></returns>
public ClientContext GetContext(string siteUrl, CancellationToken cancellationToken, string appName = "PnP", string appUrl = "https://pnp.github.io")
{
Expand All @@ -1002,8 +1020,8 @@ public async Task<ClientContext> GetContextAsync(string siteUrl)
/// </summary>
/// <param name="siteUrl"></param>
/// <param name="cancellationToken">Optional cancellation token to cancel the request</param>
/// <param name="appName">Optional app name to show when using on MacOS or Linux
/// <param name="appUrl">Optional url of app to show when using on MacOS or Linux
/// <param name="appName">Optional app name to show when using on MacOS</param>
/// <param name="appUrl">Optional url of app to show when using on MacOS</param>
/// <returns></returns>
public async Task<ClientContext> GetContextAsync(string siteUrl, CancellationToken cancellationToken, string appName = "PnP", string appUrl = "https://pnp.github.io")
{
Expand Down
34 changes: 25 additions & 9 deletions src/lib/PnP.Framework/Utilities/OAuth/DefaultBrowserUi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ internal class DefaultBrowserUi : ICustomWebUi
private Action<string, int> _openBrowserAction = null;
private string _successMessageHtml = string.Empty;
private string _failureMessageHtml = string.Empty;
public DefaultBrowserUi(Action<string, int> openBrowserAction, string successMessageHtml, string failureMessageHtml)
private bool _fullHtml = false;
public DefaultBrowserUi(Action<string, int> openBrowserAction, string successMessageHtml, string failureMessageHtml, bool fullHtml = false)
{
_openBrowserAction = openBrowserAction;
_successMessageHtml = successMessageHtml;
_failureMessageHtml = failureMessageHtml;
_fullHtml = fullHtml;
}

private const string SuccessMessageHtml = "You successfully authenticated. Feel free to close this browser/tab.";
Expand Down Expand Up @@ -107,20 +109,34 @@ private string GetMessageToShowInBrowserAfterAuth(Uri uri)
#endif
if (!string.IsNullOrEmpty(errorString))
{
if (!_fullHtml)
{
#if !NETFRAMEWORK
string errorDescription = authCodeQueryKeyValue.Get("error_description");
string errorDescription = authCodeQueryKeyValue.Get("error_description");
#else
string errorDescription = dicQueryString.ContainsKey("error_description") ? dicQueryString["error_description"] : null;
#endif
return string.Format(
CultureInfo.InvariantCulture,
CloseWindowFailureHtml,
errorString,
errorDescription,
string.IsNullOrEmpty(_failureMessageHtml) ? FailureMessageHtml : _failureMessageHtml);
return string.Format(
CultureInfo.InvariantCulture,
CloseWindowFailureHtml,
errorString,
errorDescription,
string.IsNullOrEmpty(_failureMessageHtml) ? FailureMessageHtml : _failureMessageHtml);
}
else
{
return string.Format(_failureMessageHtml, errorString);
}
}

return string.Format(CloseWindowSuccessHtml, string.IsNullOrEmpty(_successMessageHtml) ? SuccessMessageHtml : _successMessageHtml);
if (!_fullHtml)
{
return string.Format(CloseWindowSuccessHtml, string.IsNullOrEmpty(_successMessageHtml) ? SuccessMessageHtml : _successMessageHtml);
}
else
{
return _successMessageHtml;
}
}
}
}

0 comments on commit 14c215e

Please sign in to comment.