Forum Discussion
How do I update the Credentials after I upload a report to POWER BI
Jeff_973 wrote:
After I publish a report to the Power BI Service, I cannot embed the report until I set the credentials for the source of the data. Currently, I have to log into Power Bi portal and do this manually. I would like to programmatically set the credentials using the Microsoft.PowerBi.API.V2.Models SDK. Is there any good examples out there on how to do this?
I call the PowerBIClient.Datasets.GetGatewayDatasourcesInGroupWithHttpMessagesAsync to get a reference to the GatewayDatasource object and then call the PowerBIClient.Gateways.UpdateDatasourceWithHttpMessagesAsync to update the credentials. Is this correct?
One issue I am having is constructing a CredentialDetails obj which is needed to create an UpdateDatasourceRequest object which is one of the parameters to call the UpdateDatasource method.
You could check my last reply in this thread.
public static class AsymmetricKeyEncryptionHelper
{
private const int SegmentLength = 85;
private const int EncryptedLength = 128;
/// <summary>
///
/// </summary>
/// <param name="userName"></param> the datasouce user name
/// <param name="password"></param> the datasource password
/// <param name="gatewaypublicKeyExponent"></param> gateway publicKey Exponent field, you can get it from the get gateways api response json
/// <param name="gatewaypublicKeyModulus"></param> gateway publicKey Modulus field, you can get it from the get gateways api response json
/// <returns></returns>
public static string EncodeCredentials(string userName, string password, string gatewaypublicKeyExponent, string gatewaypublicKeyModulus)
{
// using json serializer to handle escape characters in username and password
var plainText = string.Format("{{\"credentialData\":[{{\"value\":{0},\"name\":\"username\"}},{{\"value\":{1},\"name\":\"password\"}}]}}", JsonConvert.SerializeObject(userName), JsonConvert.SerializeObject(password));
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(EncryptedLength * 8))
{
var parameters = rsa.ExportParameters(false);
parameters.Exponent = Convert.FromBase64String(gatewaypublicKeyExponent);
parameters.Modulus = Convert.FromBase64String(gatewaypublicKeyModulus);
rsa.ImportParameters(parameters);
return Encrypt(plainText, rsa);
}
}
private static string Encrypt(string plainText, RSACryptoServiceProvider rsa)
{
byte[] plainTextArray = Encoding.UTF8.GetBytes(plainText);
// Split the message into different segments, each segment's length is 85. So the result may be 85,85,85,20.
bool hasIncompleteSegment = plainTextArray.Length % SegmentLength != 0;
int segmentNumber = (!hasIncompleteSegment) ? (plainTextArray.Length / SegmentLength) : ((plainTextArray.Length / SegmentLength) + 1);
byte[] encryptedData = new byte[segmentNumber * EncryptedLength];
int encryptedDataPosition = 0;
for (var i = 0; i < segmentNumber; i++)
{
int lengthToCopy;
if (i == segmentNumber - 1 && hasIncompleteSegment)
lengthToCopy = plainTextArray.Length % SegmentLength;
else
lengthToCopy = SegmentLength;
var segment = new byte[lengthToCopy];
Array.Copy(plainTextArray, i * SegmentLength, segment, 0, lengthToCopy);
var segmentEncryptedResult = rsa.Encrypt(segment, true);
Array.Copy(segmentEncryptedResult, 0, encryptedData, encryptedDataPosition, segmentEncryptedResult.Length);
encryptedDataPosition += segmentEncryptedResult.Length;
}
return Convert.ToBase64String(encryptedData);
}
}
You can use it as
var credentials = AsymmetricKeyEncryptionHelper.EncodeCredentials(username, password, gateway.PublicKey.Exponent, gateway.PublicKey.Modulus);
What values would I use for the gatewaypublicKeyExponent and gatewaypublicKeyModulus?