Skip to content

Commit

Permalink
Add support for parent activity or window + customwebui
Browse files Browse the repository at this point in the history
  • Loading branch information
cheenamalhotra committed Jun 23, 2020
1 parent 83ad4ee commit 5d1cb4d
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 7 deletions.
Expand Up @@ -23,8 +23,16 @@
</AcquireTokenAsync>
<SetDeviceCodeFlowCallback>
<param name="deviceCodeFlowCallbackMethod">The callback method to be used by driver when performing 'Active Directory Device Code Flow' authentication.</param>
<summary>Set's callback method that overrides driver's default implementation to process result when performing 'Active Directory Device Code Flow' authentication.</summary>
<summary>Sets callback method that overrides driver's default implementation to process result when performing 'Active Directory Device Code Flow' authentication.</summary>
</SetDeviceCodeFlowCallback>
<SetParentActivityOrWindowFunc>
<param name="parentActivityOrWindowFunc">A function to return the current window or the parent as an object, in order to be used from shared NetStandard assemblies.</param>
<summary>Sets a reference to the ViewController (if using Xamarin.iOS), Activity (if using Xamarin.Android) IWin32Window or IntPtr (if using .Net Framework). Used for invoking the browser for Active Directory Interactive authentication.</summary>
</SetParentActivityOrWindowFunc>
<SetCustomWebUI>
<param name="customWebUi">Customer implementation for the Web UI</param>
<summary>Sets a custom Web UI that will let the user sign-in with Azure AD, present consent if needed, and get back the authorization code. Applicable when working with Active Directory Interactive authentication.</summary>
</SetCustomWebUI>
<BeforeLoad>
<param name="authentication">The authentication method.</param>
<summary>This method is called immediately before the provider is added to SQL drivers registry. </summary>
Expand Down
Expand Up @@ -8,6 +8,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Identity.Client;
using Microsoft.Identity.Client.Extensibility;

namespace Microsoft.Data.SqlClient
{
Expand All @@ -18,6 +19,8 @@ public sealed class ActiveDirectoryAuthenticationProvider : SqlAuthenticationPro
private readonly string _type = typeof(ActiveDirectoryAuthenticationProvider).Name;
private readonly SqlClientLogger _logger = new SqlClientLogger();
private Func<DeviceCodeResult, Task> _deviceCodeFlowCallback;
private Func<object> parentActivityOrWindowFunc = null;
private ICustomWebUi customWebUI = null;

/// <include file='../../../../../../doc/snippets/Microsoft.Data.SqlClient/ActiveDirectoryAuthenticationProvider.xml' path='docs/members[@name="ActiveDirectoryAuthenticationProvider"]/ctor/*'/>
public ActiveDirectoryAuthenticationProvider() => new ActiveDirectoryAuthenticationProvider(DefaultDeviceFlowCallback);
Expand Down Expand Up @@ -63,12 +66,30 @@ public ActiveDirectoryAuthenticationProvider(Func<DeviceCodeResult, Task> device
redirectURI = "http://localhost";
}
#endif
IPublicClientApplication app = PublicClientApplicationBuilder.Create(ActiveDirectoryAuthentication.AdoClientId)
IPublicClientApplication app;
if (parentActivityOrWindowFunc != null)
{
app = PublicClientApplicationBuilder.Create(ActiveDirectoryAuthentication.AdoClientId)
.WithAuthority(parameters.Authority)
.WithClientName(Common.DbConnectionStringDefaults.ApplicationName)
.WithClientVersion(Common.ADP.GetAssemblyVersion().ToString())
.WithRedirectUri(redirectURI)
#if !netcoreapp
.WithParentActivityOrWindow(parentActivityOrWindowFunc)
#endif
.Build();
}
else
{
app = PublicClientApplicationBuilder.Create(ActiveDirectoryAuthentication.AdoClientId)
.WithAuthority(parameters.Authority)
.WithClientName(Common.DbConnectionStringDefaults.ApplicationName)
.WithClientVersion(Common.ADP.GetAssemblyVersion().ToString())
.WithRedirectUri(redirectURI)
.Build();
}
if (parameters.AuthenticationMethod == SqlAuthenticationMethod.ActiveDirectoryIntegrated)
{
Expand Down Expand Up @@ -134,6 +155,7 @@ public ActiveDirectoryAuthenticationProvider(Func<DeviceCodeResult, Task> device
return new SqlAuthenticationToken(result.AccessToken, result.ExpiresOn);
});


private async Task<AuthenticationResult> AcquireTokenInteractiveDeviceFlow(IPublicClientApplication app, string[] scopes, Guid connectionId, string userId,
SqlAuthenticationMethod authenticationMethod)
{
Expand All @@ -154,7 +176,16 @@ public ActiveDirectoryAuthenticationProvider(Func<DeviceCodeResult, Task> device
{
if (authenticationMethod == SqlAuthenticationMethod.ActiveDirectoryInteractive)
{
return await app.AcquireTokenInteractive(scopes)
if (customWebUI != null)
{
return await app.AcquireTokenInteractive(scopes)
.WithCorrelationId(connectionId)
.WithCustomWebUi(customWebUI)
.WithLoginHint(userId)
.ExecuteAsync(cts.Token);
}
else
{
/*
* We will use the MSAL Embedded or System web browser which changes by Default in MSAL according to this table:
*
Expand All @@ -172,10 +203,11 @@ public ActiveDirectoryAuthenticationProvider(Func<DeviceCodeResult, Task> device
*
* https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/MSAL.NET-uses-web-browser#at-a-glance
*/
//.WithUseEmbeddedWebView(true)
.WithCorrelationId(connectionId)
.WithLoginHint(userId)
.ExecuteAsync(cts.Token);
return await app.AcquireTokenInteractive(scopes)
.WithCorrelationId(connectionId)
.WithLoginHint(userId)
.ExecuteAsync(cts.Token);
}
}
else
{
Expand Down Expand Up @@ -211,6 +243,19 @@ private Task DefaultDeviceFlowCallback(DeviceCodeResult result)
/// <include file='../../../../../../doc/snippets/Microsoft.Data.SqlClient/ActiveDirectoryAuthenticationProvider.xml' path='docs/members[@name="ActiveDirectoryAuthenticationProvider"]/SetDeviceCodeFlowCallback/*'/>
public void SetDeviceCodeFlowCallback(Func<DeviceCodeResult, Task> deviceCodeFlowCallbackMethod) => _deviceCodeFlowCallback = deviceCodeFlowCallbackMethod;

/// <include file='../../../../../../doc/snippets/Microsoft.Data.SqlClient/ActiveDirectoryAuthenticationProvider.xml' path='docs/members[@name="ActiveDirectoryAuthenticationProvider"]/SetParentActivityOrWindowFunc/*'/>
public void SetParentActivityOrWindowFunc(Func<object> parentActivityOrWindowFunc)
{
this.parentActivityOrWindowFunc = parentActivityOrWindowFunc;
}

/// <include file='../../../../../../doc/snippets/Microsoft.Data.SqlClient/ActiveDirectoryAuthenticationProvider.xml' path='docs/members[@name="ActiveDirectoryAuthenticationProvider"]/SetCustomWebUI/*'/>
public void SetCustomWebUI(ICustomWebUi customWebUi)
{

customWebUI = customWebUi;
}

/// <include file='../../../../../../doc/snippets/Microsoft.Data.SqlClient/ActiveDirectoryAuthenticationProvider.xml' path='docs/members[@name="ActiveDirectoryAuthenticationProvider"]/IsSupported/*'/>
public override bool IsSupported(SqlAuthenticationMethod authentication)
{
Expand Down

0 comments on commit 5d1cb4d

Please sign in to comment.