-
Notifications
You must be signed in to change notification settings - Fork 316
Introduce support for AAD Device Code Flow authentication #597
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
Merged
Merged
Changes from 15 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
7687984
Introduce support for AAD Device Code Flow authentication
cheenamalhotra ae41144
Add tests + sample = modified implementation
cheenamalhotra fa6aa17
Reflect comments + cleanup
cheenamalhotra be825fd
Merge branch 'master' into DeviceCodeFlow
cheenamalhotra da572e7
Apply suggestions from code review
cheenamalhotra c9bff31
Do not log to console with LogError
cheenamalhotra aa754c7
Make Active Directory Authentication Provider public
cheenamalhotra 1a99c9d
Improvements
cheenamalhotra 4c22829
Add refs + sealed class
cheenamalhotra 83ad4ee
Merge branch 'master' of https://github.com/dotnet/SqlClient into Dev…
cheenamalhotra 4b34acf
New APIs for custom window/UI support for AD Interactive authentication
cheenamalhotra f1be61f
More changes
cheenamalhotra 095237b
Apply suggestions from code review
cheenamalhotra a6cd921
Update API to accept Function as parameter
cheenamalhotra b15a202
Apply suggestions from code review
cheenamalhotra 146d563
Edits
cheenamalhotra eb6149e
Merge branch 'master' of https://github.com/dotnet/SqlClient into Dev…
cheenamalhotra File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| //<Snippet1> | ||
| using System; | ||
| using System.Threading.Tasks; | ||
| using Microsoft.Identity.Client; | ||
| using Microsoft.Data.SqlClient; | ||
|
|
||
| namespace CustomAuthenticationProviderExamples | ||
| { | ||
| public class Program | ||
| { | ||
| public static void Main() | ||
| { | ||
| SqlAuthenticationProvider authProvider = new ActiveDirectoryAuthenticationProvider(CustomDeviceFlowCallback); | ||
| SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow, authProvider); | ||
| using (SqlConnection sqlConnection = new SqlConnection("Server=<myserver>.database.windows.net;Authentication=Active Directory Device Code Flow;Database=<db>;")) | ||
| { | ||
| sqlConnection.Open(); | ||
| Console.WriteLine("Connected successfully!"); | ||
| } | ||
| } | ||
|
|
||
| private Task CustomDeviceFlowCallback(DeviceCodeResult result) | ||
| { | ||
| // Provide custon logic to process result information and read device code. | ||
cheenamalhotra marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Console.WriteLine(result.Message); | ||
| return Task.FromResult(0); | ||
| } | ||
| } | ||
| } | ||
| //</Snippet1> | ||
56 changes: 56 additions & 0 deletions
56
doc/samples/CustomDeviceCodeFlowAzureAuthenticationProvider.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| //<Snippet1> | ||
| using System; | ||
| using System.Threading.Tasks; | ||
| using Microsoft.Identity.Client; | ||
| using Microsoft.Data.SqlClient; | ||
|
|
||
| namespace CustomAuthenticationProviderExamples | ||
| { | ||
| /// <summary> | ||
| /// Example demonstrating creating a custom device code flow authentication provider and attaching it to the driver. | ||
| /// This is helpful for applications that wish to override the Callback for the Device Code Result implemented by the SqlClient driver. | ||
| /// </summary> | ||
| public class CustomDeviceCodeFlowAzureAuthenticationProvider : SqlAuthenticationProvider | ||
| { | ||
| public override async Task<SqlAuthenticationToken> AcquireTokenAsync(SqlAuthenticationParameters parameters) | ||
| { | ||
| string clientId = "my-client-id"; | ||
cheenamalhotra marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| string clientName = "My Application Name"; | ||
| string s_defaultScopeSuffix = "/.default"; | ||
|
|
||
| string[] scopes = new string[] { parameters.Resource.EndsWith(s_defaultScopeSuffix) ? parameters.Resource : parameters.Resource + s_defaultScopeSuffix }; | ||
|
|
||
| IPublicClientApplication app = PublicClientApplicationBuilder.Create(clientId) | ||
| .WithAuthority(parameters.Authority) | ||
| .WithClientName(clientName) | ||
| .WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient") | ||
| .Build(); | ||
|
|
||
| AuthenticationResult result = await app.AcquireTokenWithDeviceCode(scopes, | ||
| deviceCodeResult => CustomDeviceFlowCallback(deviceCodeResult)).ExecuteAsync(); | ||
cheenamalhotra marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return new SqlAuthenticationToken(result.AccessToken, result.ExpiresOn); | ||
| } | ||
|
|
||
| public override bool IsSupported(SqlAuthenticationMethod authenticationMethod) => authenticationMethod.Equals(SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow); | ||
|
|
||
| private Task CustomDeviceFlowCallback(DeviceCodeResult result) | ||
| { | ||
| Console.WriteLine(result.Message); | ||
| return Task.FromResult(0); | ||
| } | ||
| } | ||
|
|
||
| public class Program | ||
| { | ||
| public static void Main() | ||
| { | ||
| SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow, new CustomDeviceCodeFlowAzureAuthenticationProvider()); | ||
| using (SqlConnection sqlConnection = new SqlConnection("Server=<myserver>.database.windows.net;Authentication=Active Directory Device Code Flow;Database=<db>;")) | ||
| { | ||
| sqlConnection.Open(); | ||
| Console.WriteLine("Connected successfully!"); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| //</Snippet1> | ||
83 changes: 83 additions & 0 deletions
83
doc/snippets/Microsoft.Data.SqlClient/ActiveDirectoryAuthenticationProvider.xml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| <docs> | ||
| <members name="ActiveDirectoryAuthenticationProvider"> | ||
| <ActiveDirectoryAuthenticationProvider> | ||
| <summary> | ||
| This class implements <see cref="T:Microsoft.Data.SqlClient.SqlAuthenticationProvider" /> and is used for active directory federated authentication mechanisms. | ||
| </summary> | ||
| </ActiveDirectoryAuthenticationProvider> | ||
| <ctor> | ||
| <summary> | ||
| Initializes the <see cref="T:Microsoft.Data.SqlClient.ActiveDirectoryAuthenticationProvider" /> class. | ||
| </summary> | ||
| </ctor> | ||
| <ctor2> | ||
| <param name="deviceCodeFlowCallbackMethod">The callback method to be used when performing 'Active Directory Device Code Flow' authentication.</param> | ||
| <summary> | ||
| Initializes the <see cref="T:Microsoft.Data.SqlClient.ActiveDirectoryAuthenticationProvider" /> class with the provided device code flow callback method. | ||
| </summary> | ||
| </ctor2> | ||
| <AcquireTokenAsync> | ||
| <param name="parameters">The Active Directory authentication parameters passed to authentication providers.</param> | ||
| <summary>Acquires a security token from the authority.</summary> | ||
| <returns>Represents an asynchronous operation that returns the authentication token.</returns> | ||
| </AcquireTokenAsync> | ||
| <SetDeviceCodeFlowCallback> | ||
| <param name="deviceCodeFlowCallbackMethod">The callback method to be used when performing 'Active Directory Device Code Flow' authentication.</param> | ||
| <summary>Sets the callback method, overriding the default implementation that processes the result when performing 'Active Directory Device Code Flow' authentication.</summary> | ||
| </SetDeviceCodeFlowCallback> | ||
| <SetParentActivityOrWindowFunc> | ||
| <param name="parentActivityOrWindowFunc">The parent as an object, in order to be used from shared .NET Standard 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> | ||
| <remarks>Mandatory to be set only on Android. See https://aka.ms/msal-net-android-activity for further documentation and details.</remarks> | ||
| </SetParentActivityOrWindowFunc> | ||
| <SetIWin32WindowFunc> | ||
| <param name="iWin32WindowFunc">A function to return the current window.</param> | ||
| <summary>Sets a reference to the current <see cref="T:System.Windows.Forms.IWin32Window" /> that triggers the browser to be shown. Used to center the browser pop-up onto this window."</summary> | ||
| </SetIWin32WindowFunc> | ||
| <SetAcquireAuthorizationCodeAsyncCallback> | ||
| <param name="acquireAuthorizationCodeAsyncCallback">The callback method to be called by MSAL.NET to delegate the Web user interface with the Secure Token Service (STS).</param> | ||
| <summary>Sets a callback method which is invoked with a custom Web UI instance that will let the user sign-in with Azure Active Directory, present consent if needed, and get back the authorization code. Applicable when working with Active Directory Interactive authentication.</summary> | ||
| <remarks>The "authorizationUri" is crafted to leverage PKCE in order to protect the token from a man in the middle attack. Only MSAL.NET can redeem the code. In the event of cancellation, the implementer should return <see cref="T:System.OperationCanceledException" />.</remarks> | ||
| </SetAcquireAuthorizationCodeAsyncCallback> | ||
| <BeforeLoad> | ||
| <param name="authentication">The authentication method.</param> | ||
| <summary>This method is called immediately before the provider is added to authentication provider registry. </summary> | ||
| <remarks>Avoid performing long-waiting tasks in this method, since it can block other threads from accessing the provider registry.</remarks> | ||
| </BeforeLoad> | ||
| <BeforeUnload> | ||
| <param name="authentication">The authentication method.</param> | ||
| <summary>This method is called immediately before the provider is removed from the authentication provider registry. </summary> | ||
| <remarks>For example, this method is called when a different provider with the same authentication method overrides this provider in the authentication provider registry. Avoid performing long-waiting task in this method, since it can block other threads from accessing the provider registry.</remarks> | ||
| </BeforeUnload> | ||
| <IsSupported> | ||
| <param name="authentication">The authentication method.</param> | ||
| <summary>Indicates whether the specified authentication method is supported.</summary> | ||
| <returns> | ||
| <see langword="true" /> if the specified authentication method is supported; otherwise, <see langword="false" />. | ||
| </returns> | ||
| <remarks> | ||
| <format type="text/markdown"> | ||
| <] | ||
|
|
||
| ]]> | ||
| </format> | ||
| </remarks> | ||
| </IsSupported> | ||
| </members> | ||
| </docs> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 66 additions & 47 deletions
113
doc/snippets/Microsoft.Data.SqlClient/SqlAuthenticationProvider.xml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,49 +1,68 @@ | ||
| <docs> | ||
| <members name="SqlAuthenticationProvider"> | ||
| <SqlAuthenticationProvider> | ||
| <summary>Defines the core behavior of authentication providers and provides a base class for derived classes. </summary> | ||
| <remarks>Derived classes must provide a parameterless constructor if they can be instantiated from the app.config file.</remarks> | ||
| </SqlAuthenticationProvider> | ||
| <ctor> | ||
| <summary>Called from constructors in derived classes to initialize the <see cref="T:Microsoft.Data.SqlClient.SqlAuthenticationProvider" /> class.</summary> | ||
| </ctor> | ||
| <GetProvider> | ||
| <param name="authenticationMethod">The authentication method.</param> | ||
| <summary>Gets an authentication provider by method.</summary> | ||
| <returns>The authentication provider or <see langword="null" /> if not found.</returns> | ||
| <remarks>To be added.</remarks> | ||
| </GetProvider> | ||
| <SetProvider> | ||
| <param name="authenticationMethod">The authentication method.</param> | ||
| <param name="provider">The authentication provider.</param> | ||
| <summary>Sets an authentication provider by method.</summary> | ||
| <returns> | ||
| <see langword="true" /> if the operation succeeded; otherwise, <see langword="false" /> (for example, the existing provider disallows overriding). | ||
| </returns> | ||
| <remarks>To be added.</remarks> | ||
| </SetProvider> | ||
| <BeforeLoad> | ||
| <param name="authenticationMethod">The authentication method.</param> | ||
| <summary>This method is called immediately before the provider is added to SQL drivers registry. </summary> | ||
| <remarks>Avoid performing long-waiting tasks in this method, since it can block other threads from accessing the provider registry.</remarks> | ||
| </BeforeLoad> | ||
| <BeforeUnload> | ||
| <param name="authenticationMethod">The authentication method.</param> | ||
| <summary>This method is called immediately before the provider is removed from the SQL drivers registry. </summary> | ||
| <remarks>For example, this method is called when a different provider with the same authentication method overrides this provider in the SQL drivers registry. Avoid performing long-waiting task in this method, since it can block other threads from accessing the provider registry.</remarks> | ||
| </BeforeUnload> | ||
| <IsSupported> | ||
| <param name="authenticationMethod">The authentication method.</param> | ||
| <summary>Indicates whether the specified authentication method is supported.</summary> | ||
| <returns> | ||
| <see langword="true" /> if the specified authentication method is supported; otherwise, <see langword="false" />.</returns> | ||
| <remarks>To be added.</remarks> | ||
| </IsSupported> | ||
| <AcquireTokenAsync> | ||
| <param name="parameters">The Active Directory authentication parameters passed by the driver to authentication providers.</param> | ||
| <summary>Acquires a security token from the authority.</summary> | ||
| <returns>Represents an asynchronous operation that returns the AD authentication token.</returns> | ||
| <remarks>To be added.</remarks> | ||
| </AcquireTokenAsync> | ||
| </members> | ||
| <members name="SqlAuthenticationProvider"> | ||
| <SqlAuthenticationProvider> | ||
| <summary>Defines the core behavior of authentication providers and provides a base class for derived classes. </summary> | ||
| <remarks> | ||
| <format type="text/markdown"> | ||
| <] | ||
|
|
||
| ]]> | ||
| </format> | ||
| </remarks> | ||
| </SqlAuthenticationProvider> | ||
| <ctor> | ||
| <summary> | ||
| Called from constructors in derived classes to initialize the <see cref="T:Microsoft.Data.SqlClient.SqlAuthenticationProvider" /> class. | ||
| </summary> | ||
| </ctor> | ||
| <GetProvider> | ||
| <param name="authenticationMethod">The authentication method.</param> | ||
| <summary>Gets an authentication provider by method.</summary> | ||
| <returns> | ||
| The authentication provider or <see langword="null" /> if not found. | ||
| </returns> | ||
| <remarks>To be added.</remarks> | ||
| </GetProvider> | ||
| <SetProvider> | ||
| <param name="authenticationMethod">The authentication method.</param> | ||
| <param name="provider">The authentication provider.</param> | ||
| <summary>Sets an authentication provider by method.</summary> | ||
| <returns> | ||
| <see langword="true" /> if the operation succeeded; otherwise, <see langword="false" /> (for example, the existing provider disallows overriding). | ||
| </returns> | ||
| <remarks>To be added.</remarks> | ||
| </SetProvider> | ||
| <BeforeLoad> | ||
| <param name="authenticationMethod">The authentication method.</param> | ||
| <summary>This method is called immediately before the provider is added to SQL drivers registry. </summary> | ||
| <remarks>Avoid performing long-waiting tasks in this method, since it can block other threads from accessing the provider registry.</remarks> | ||
| </BeforeLoad> | ||
| <BeforeUnload> | ||
| <param name="authenticationMethod">The authentication method.</param> | ||
| <summary>This method is called immediately before the provider is removed from the SQL drivers registry. </summary> | ||
| <remarks>For example, this method is called when a different provider with the same authentication method overrides this provider in the SQL drivers registry. Avoid performing long-waiting task in this method, since it can block other threads from accessing the provider registry.</remarks> | ||
| </BeforeUnload> | ||
| <IsSupported> | ||
| <param name="authenticationMethod">The authentication method.</param> | ||
| <summary>Indicates whether the specified authentication method is supported.</summary> | ||
| <returns> | ||
| <see langword="true" /> if the specified authentication method is supported; otherwise, <see langword="false" />. | ||
| </returns> | ||
| <remarks>To be added.</remarks> | ||
| </IsSupported> | ||
| <AcquireTokenAsync> | ||
| <param name="parameters">The Active Directory authentication parameters passed by the driver to authentication providers.</param> | ||
| <summary>Acquires a security token from the authority.</summary> | ||
| <returns>Represents an asynchronous operation that returns the AD authentication token.</returns> | ||
| <remarks>To be added.</remarks> | ||
| </AcquireTokenAsync> | ||
| </members> | ||
| </docs> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.NetStandard.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
| // See the LICENSE file in the project root for more information. | ||
| // ------------------------------------------------------------------------------ | ||
| // Changes to this file must follow the http://aka.ms/api-review process. | ||
| // ------------------------------------------------------------------------------ | ||
|
|
||
| namespace Microsoft.Data.SqlClient | ||
| { | ||
| /// <include file='../../../../doc/snippets/Microsoft.Data.SqlClient/ActiveDirectoryAuthenticationProvider.xml' path='docs/members[@name="ActiveDirectoryAuthenticationProvider"]/ActiveDirectoryAuthenticationProvider/*'/> | ||
| public sealed partial class ActiveDirectoryAuthenticationProvider : SqlAuthenticationProvider | ||
| { | ||
| /// <include file='../../../../doc/snippets/Microsoft.Data.SqlClient/ActiveDirectoryAuthenticationProvider.xml' path='docs/members[@name="ActiveDirectoryAuthenticationProvider"]/SetParentActivityOrWindowFunc/*'/> | ||
| public void SetParentActivityOrWindowFunc(System.Func<object> parentActivityOrWindowFunc) { } | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.