OAuth is an open standard that defines how clients unlinked to a service can be authorized by a registered user of that service for limited access on behalf of the user, without sharing the user's credentials and full rights. For each particular authorization by the registered user, the host of the service issues a different set of credentials.
DataConnector facilitates OAuth by supporting both user credentials (username and password) and client credentials (id and secret). The DataConnector API uses the connection string to automatically generate tokens (access and refresh), which are directly consumed by the connection to provide authorized access to the data source. It can be implemented by setting the following attributes of the connection string (or the respective properties of connection-string-builder classes):
Attribute | Description |
---|---|
OAuth Client Id | The identifier issued to the OAuth 2.0 client during the registration process. |
OAuth Client Secret | The secret provided to the OAuth 2.0 client during the registration process. |
OAuth Access Token |
The access token to be used for the OAuth 2.0 authorization. Tokens must be kept confidential in transit and storage. |
OAuth Refresh Token |
The refresh token to be used for the OAuth 2.0 authorization. Tokens must be kept confidential in transit and storage. |
OAuth Token Endpoint | The endpoint for the OAuth 2.0 tokens. |
OAuth Extend Properties |
This is designed to support any custom information that users may have to add to the connection string, for the library to obtain proper tokens. Not needed by some services (e.g. OData). |
OAuth Scope | The scope for the OAuth 2.0 authorization request. |
The connection string can be constructed with the Username and Password credentials provided by the resource owner, as in the code example below:
C# |
Copy Code |
---|---|
const string urlDynamics = @"https://xxx.xxx.xxx.xxx.com/api/data/v9.1/"; const string username = "****"; const string password = "****"; const string tokenEnpoint = @"https://login.microsoftonline.com/common/oauth2/token"; const string extendProperties = @"{""resource"":""https://xxx.xxx.xxx.com/""}"; string connstr = $@"Url={urlDynamics};Use Cache=true;Use Etag=true;Username={username};Password={password}; OAuth Token Endpoint={tokenEnpoint};OAuth Extend Properties={extendProperties};Max Page Size = 100"; |
The same can be achieved through passing in the connection string the OAuth Client Id and OAuth Client Secret credentials provided to the client by the host of the service, as in the code below:
C# |
Copy Code |
---|---|
const string urlDynamics = @"https://xxx.xxx.xxx.xxx.com/api/data/v9.1/"; const string clientID = "****";const string clientSecret = "****" const string tokenEnpoint = @"https://login.microsoftonline.com/common/oauth2/token"; const string extendProperties = @"{""resource"":""https://xxx.xxx.xxx.com/""}"; string connstr = $@"Url={urlDynamics};Use Etag=true;OAuth Client Id={clientID};OAuth Client Secret={clientSecret}; OAuth Token Endpoint={tokenEnpoint};OAuth Extend Properties={extendProperties};Max Page Size = 100"; |
If the user already possesses the OAuth Access Token and OAuth Refresh Token, doesn't have to re-obtain them, but can use them to connect directly, like in the code below:
C# |
Copy Code |
---|---|
const string urlDynamics = @"https://xxx.xxx.xxx.xxx.com/api/data/v9.1/"; const string clientID = "****"; const string cllentSecret = "****"; const string accessToken = "<real access token>"; const string refreshToken = "<real refresh token>"; const string tokenEnpoint = @"https://login.microsoftonline.com/common/oauth2/token"; static string connstr = $@"Url={urlDynamics};OAuth Access Token={accessToken};OAuth Refresh Token={refreshToken};OAuth Client Id={clientID}; OAuth Client Secret={cllentSecret};OAuth Token Endpoint={tokenEnpoint};Use Etag=true;Use Connection Pooling=true"; |
After constructing the connection string in any of the above ways, it can be used to connect and retrieve the data like in the following code example:
C# |
Copy Code |
---|---|
using (var con = new C1D365SConnection(connstr)) // Create connection using connection string as parameter { // Open connection con.Open(); // Create Command var cmd = con.CreateCommand(); cmd.CommandText = "Select accountid, name FROM Accounts limit 10'"; // Execute Reader var rdr = cmd.ExecuteReader(); // Use Reader to display the data while (rdr.Read()) { Console.WriteLine(String.Format("\t{0} --> \t\t{1}", rdr["accountid"], rdr["name"])); } } |