I'm new to Office 365 and SharePoint, while I'm trying to create a SharePoint site using CSOM in .NET I've used Tenant like (var tenant = new Tenant(clientContext);) can someone explain what "Tenant" exactly is and what is the use of it in here. When I searched for it I learnt something like Tenant ID which Unique for each Company, but Tenant ID and Tenant in CSOM is different right? and also What is ClientContext? in my code I have used both ClientContext and Tenant to create a SharePoint Site.
using System;
using System.Security;
using Microsoft.Online.SharePoint.TenantAdministration;
using Microsoft.SharePoint.Client;
namespace CreateSiteCollections
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Program Started!");
//Opens the Admin URL
using(ClientContext tenantContext=new ClientContext("https://developer19-admin.sharepoint.com/"))
{
//Authenticating with Tenant Admin
SecureString passWord = new SecureString();
foreach (char c in "passCode1".ToCharArray())
passWord.AppendChar(c);
tenantContext.Credentials = new SharePointOnlineCredentials("kailash#developer19.onmicrosoft.com", passWord);
var tenant = new Tenant(tenantContext);
//Properties
var siteCreationProperties = new SiteCreationProperties();
//New-Site URL
siteCreationProperties.Url = "https://developer19.sharepoint.com/sites/codesite";
//Titie of the Root Site
siteCreationProperties.Title = "Coded Site";
//Login Name
siteCreationProperties.Owner = "kailash#developer19.onmicrosoft.com";
//Template Copied from Team Site
siteCreationProperties.Template = "STS#0";
//Storage Limit in MB
siteCreationProperties.StorageMaximumLevel = 100;
//UserCode resourse Points Allowed
siteCreationProperties.UserCodeMaximumLevel = 50;
//Creates Site Collection
SpoOperation spo = tenant.CreateSite(siteCreationProperties);
tenantContext.Load(tenant);
//IsComplete to check if provisioning is Completed
tenantContext.Load(spo, i => i.IsComplete);
tenantContext.ExecuteQuery();
while(!spo.IsComplete)
{
//Waits 30 Sec and tries again
System.Threading.Thread.Sleep(30000);
spo.RefreshLoad();
tenantContext.ExecuteQuery();
}
Console.WriteLine("SiteCollection Created.");
}
}
}
}
A Tenant is the Organisation or the Company. It's the "instance of Office 365" that is unique to your user base.
While it's not necessarily a single domain name, because a Tenant could have multiple domain names, that's one way to think of it.
A tenancy in Office 365 refers to the full Office 365 suite attached
to a domain. When Office 365 is set up, it creates a tenancy to store
all the data for Office 365 including things like SharePoint, OneDrive
and Yammer. This allows all of your organisations data to sit in the
same environment and be moved around within the tenant with ease.
Related
I have been trying WITH NO LUCK, to get an embed token to be able to embed my powerbi reports into my existing .netcore web api application. The front end looks like a super easy 1 simple react component that power bi has prepared for me.
But for the backend, I'm literally going in circles.
I got to the point where I decided the cleanest way for me to do this would be through an HTTP Trigger function.
(see this: https://www.taygan.co/blog/2018/05/14/embedded-analytics-with-power-bi )
As an important side note: I DID already grant my application the necessary delegate READ permissions to the power bi Apis)
Another side note, is that I am attempting to do the master user, app owns data approach
Another side note, is that you will see that my link above, the code shows you to get an AAD auth token using a method that is no longer supported (seemingly) by microsoft, so I changed that line of code as you'll see below
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.PowerBI.Api;
using Microsoft.PowerBI.Api.Models;
using Microsoft.Rest;
using Newtonsoft.Json;
namespace PowerBiExample
{
public class EmbedContent
{
public string EmbedToken { get; set; }
public string EmbedUrl { get; set; }
public string ReportId { get; set; }
}
public static class Test
{
private static string tenantId = "this is the id of my entire organization";
static string authorityUrl = $"https://login.microsoftonline.com/{tenantId}";
static string resourceUrl = "https://analysis.windows.net/powerbi/api";
static string apiUrl = "https://api.powerbi.com/";
private static string clientId = "this is the client id of my application that i gave delegate permissions to";
private static string clientSecret = "this is the secret of the application i gave delegate permissions to";
private static string username = "ad master user that i WANTED to sign into power bi with";
private static string password = "that ad users pw";
private static Guid groupId = Guid.Parse("workspaceid in powerbi");
private static Guid reportId = Guid.Parse("report id from within that workspace");
[FunctionName("Test")]
public static async Task<IActionResult> RunAsync(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log)
{
var credential = new ClientCredential(clientId, clientSecret);
var authenticationContext = new AuthenticationContext(authorityUrl);
// var authenticationResult = await authenticationContext.AcquireTokenAsync(resourceUrl, clientId, credential);
var authenticationResult = await authenticationContext.AcquireTokenAsync(resourceUrl, credential);
string accessToken = authenticationResult.AccessToken;
var tokenCredentials = new TokenCredentials(accessToken, "Bearer");
using (var client = new PowerBIClient(new Uri(apiUrl), tokenCredentials))
{
// Embed URL
Report report = client.Reports.GetReportInGroup(groupId, reportId);
string embedUrl = report.EmbedUrl;
// Embed Token
var generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view");
EmbedToken embedToken = client.Reports.GenerateTokenInGroup(groupId, reportId, generateTokenRequestParameters);
// JSON Response
EmbedContent data = new EmbedContent();
data.EmbedToken = embedToken.Token;
data.EmbedUrl = embedUrl;
data.ReportId = reportId.ToString();
var s = JsonConvert.SerializeObject(data);
return new JsonResult(s);
// JavaScriptSerializer js = new JavaScriptSerializer();
// string jsonp = "callback(" + js.Serialize(data) + ");";
//
// // Return Response
// return new HttpResponseMessage(HttpStatusCode.OK)
// {
// Content = new StringContent(jsonp, Encoding.UTF8, "application/json")
// };
}
}
}
}
I DO get the Authorization Token returned. I DO NOT get the Embed Token returned. I get unauthorized for that.
Also important note: 1. I also didn't enable Service Principal like it says to do here learn.microsoft.com/en-us/power-bi/enterprise/… (my IT dept said I can't). and 2. they are not an admin or member on the workspace but when I try to add them as member, they are not available. It's an Application, not a user or a group. What should I do
Please check if below points can give an idea to work around.
A fiddler trace may be required to investigate further. The required
permission scope may be missing for the registered application
within Azure AD. Verify the required scope is present within the
app registration for Azure AD within the Azure portal ex: openid ,
profile, offline etc depending on the requirement and the user
logged in.
When using a master user, you'll need to define your app's delegated
permissions ( known as scopes). The master user or Power BI
admin is required to grant consent for using these permissions using
the Power BI REST APIs.
For master users, it is essential to grant permissions from the
Azure portal.
Also check if the group Id provided is correct,
Also For Analysis Services, the master user has to be a
gateway admin.
Your web app uses a user account to authenticate against Azure AD
and get the Azure AD token. The master user needs to have a Power
BI Pro or a Premium Per User (PPU) license.
After successful authentication against Azure AD, your web app will
generate an embed token to allow its users to access specific
Power BI content.
Please go through this considerations to generate embed token
carefully and give proper permissions.
Note: For security reasons, the lifetime of the embed token is set to the remaining lifetime of the Azure AD token used to call the
GenerateToken API.
Therefore, if you use the same Azure AD token to generate several embed tokens, the lifetime of the generated embed tokens will be shorter with each call.
Sometimes that can be the reason for the unauthorized error due to expiry of embed token
Please check this powerbi-docs/embedded-troubleshoot.md at live ·
MicrosoftDocs/powerbi-docs · GitHub to see several issues and
find what is the main issue in your case.
And also check if you need to provide datasetId
Some references:
Unauthorized response on GetReportInGroupAsync PowerBI Embedded
API call using Service Principal - Stack Overflow
Register an app to embed Power BI content in a Power BI embedded
analytics application - Power BI | Microsoft Docs
Understand the permission tokens needed for embedding a Power BI
application - Power BI | Microsoft Docs
I need to save files from the existing AngularJS/.NET application to Sharepoint. Most of the examples I see online is when applications reside on Sharepoint itself. How do I save files from outside?
I've been given a user access to our organization's Sharepoint site but no application user passwords. What do I need to request from administrators of SharePoint site to be able to write the code?
We can use CSOM C# code to upload file to SharePoint 2010 document library. We need use an admin user and password to pass the Credentials in the .NET application server.
public static void UploadFile(ClientContext context, string uploadFolderUrl, string uploadFilePath)
{
var fileCreationInfo = new FileCreationInformation
{
Content = System.IO.File.ReadAllBytes(uploadFilePath),
Overwrite = true,
Url = Path.GetFileName(uploadFilePath)
};
var targetFolder = context.Web.GetFolderByServerRelativeUrl(uploadFolderUrl);
var uploadFile = targetFolder.Files.Add(fileCreationInfo);
context.Load(uploadFile);
context.ExecuteQuery();
}
Usage
var siteUrl="http://sp2010";
var username="admin";
var password="xx";
var domainName="domain1";
using (var ctx = new ClientContext(webUri))
{
ctx.Credentials = new System.Net.NetworkCredential(username, password, domainName);
UploadFile(ctx,"Documents/folder1",#"c:\upload\test.docx");
}
The following article for your reference.
Uploading files using Client Object Model in SharePoint 2010
I have a website called www.Request.com, when users access this site they will be able to request the creation of a new instance of another website that is already deployed in AZURE with the name www.MyTechnicalApp.com
for example when I access to www.Request.com I will request the creation of MyTechnicalApp for my company called "MyCompany", it's supposed that there is a script that will be executed by request.com website to create automatically www.MyCompany.MyTechnicalApp.com website.
would you please let me know how could I do that?
According to your description, to create a web app on Azure automatically, there are two ways to achieve this.
One: using "Windows Azure Management Libraries", this SDK is a wrapper around "Azure Service Management" API.
First, we need to do authentication with ASM API and we can refer to: Windows Azure Management Librairies : Introduction et authentification, then we will be able to create a website with something like this:
using (var AwsManagement = new Microsoft.WindowsAzure.Management.WebSites.WebSiteManagementClient(azureCredentials))
{
WebSiteCreateParameters parameters = new WebSiteCreateParameters()
{
Name = "myAws",
// this Service Plan must be created before
ServerFarm = "myServiceplan",
};
await AwsManagement.WebSites.CreateAsync("myWebSpace", parameters, CancellationToken.None);
}
Two: We can create a web site by using a POST request that includes the name of the web site and other information in the request body. We can check the code example for azure-sdk-for-net
use this link to get the credentials Authentication in Azure Management Libraries for Java.
https://github.com/Azure/azure-libraries-for-java/blob/master/AUTH.md
The below link helped me to find the answer.
static void Main(string[] args)
{
try
{
var resourceGroupName = "your ressource group name";
var subId = "64da6c..-.......................88d";
var appId = "eafeb071-3a70-40f6-9e7c-fb96a6c4eabc";
var appSecret = "YNlNU...........................=";
var tenantId = "c5935337-......................19";
var environment = AzureEnvironment.AzureGlobalCloud;
var credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(appId, appSecret, tenantId, AzureEnvironment.AzureGlobalCloud);
var azure = Microsoft.Azure.Management.Fluent.Azure
.Configure()
.Authenticate(credentials)
.WithSubscription(subId);
azure.AppServices.WebApps.Inner.CreateOrUpdateHostNameBindingWithHttpMessagesAsync(resourceGroupName, "WebSiteName", "SubDomainName",
new HostNameBindingInner(
azureResourceType: AzureResourceType.Website,
hostNameType: HostNameType.Verified,
customHostNameDnsRecordType: CustomHostNameDnsRecordType.CName)).Wait();
}
catch (Exception ex)
{
}
}
I am modifying an internal management application to connect to our online hosted Dynamics 2016 instance.
Following some online tutorials, I have been using an OrganizationServiceProxy out of Microsoft.Xrm.Sdk.Client from the SDK.
This seems to need a username and password to connect, which works fine, but I would like to connect in some way that doesn't require a particular user's account details. I don't think the OAuth examples I've seen are suitable, as there is no UI, and no actual person to show an OAuth request to.
public class DynamicsHelper
{
private OrganizationServiceProxy service;
public void Connect(string serviceUri, string username, string password)
{
var credentials = new ClientCredentials();
credentials.UserName.UserName = username;
credentials.UserName.Password = password;
var organizationUri = new Uri(serviceUri);
this.service = new OrganizationServiceProxy(organizationUri, null, credentials, null);
}
}
Is there a way to connect with an application token or API key?
I've found that to do this successfully, you'll need to setup all of the following:
Create an application registration in Azure AD:
grant it API permissions for Dynamics, specifically "Access Dynamics 365 as organization users"
give it a dummy web redirect URI such as http://localhost/auth
generate a client secret and save it for later
Create a user account in Azure AD and give it permissions to Dynamics.
Create an application user record in Dynamics with the same email as the non-interactive user account above.
Authenticate your application using the user account you've created.
For step 4, you'll want to open an new incognito window, construct a url using the following pattern and login using your user account credentials in step 2:
https://login.microsoftonline.com/<your aad tenant id>/oauth2/authorize?client_id=<client id>&response_type=code&redirect_uri=<redirect uri from step 1>&response_mode=query&resource=https://<organization name>.<region>.dynamics.com&state=<random value>
When this is done, you should see that your Dynamics application user has an Application ID and Application ID URI.
Now with your ClientId and ClientSecret, along with a few other organization specific variables, you can authenticate with Azure Active Directory (AAD) to acquire an oauth token and construct an OrganizationWebProxyClient. I've never found a complete code example of doing this, but I have developed the following for my own purposes. Note that the token you acquire has an expiry of 1 hr.
internal class ExampleClientProvider
{
// Relevant nuget packages:
// <package id="Microsoft.CrmSdk.CoreAssemblies" version="9.0.2.9" targetFramework="net472" />
// <package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="4.5.1" targetFramework="net461" />
// Relevant imports:
// using Microsoft.IdentityModel.Clients.ActiveDirectory;
// using Microsoft.Crm.Sdk.Messages;
// using Microsoft.Xrm.Sdk;
// using Microsoft.Xrm.Sdk.Client;
// using Microsoft.Xrm.Sdk.WebServiceClient;
private const string TenantId = "<your aad tenant id>"; // from your app registration overview "Directory (tenant) ID"
private const string ClientId = "<your client id>"; // from your app registration overview "Application (client) ID"
private const string ClientSecret = "<your client secret>"; // secret generated in step 1
private const string LoginUrl = "https://login.microsoftonline.com"; // aad login url
private const string OrganizationName = "<your organization name>"; // check your dynamics login url, e.g. https://<organization>.<region>.dynamics.com
private const string OrganizationRegion = "<your organization region>"; // might be crm for north america, check your dynamics login url
private string GetServiceUrl()
{
return $"{GetResourceUrl()}/XRMServices/2011/Organization.svc/web";
}
private string GetResourceUrl()
{
return $"https://{OrganizationName}.api.{OrganizationRegion}.dynamics.com";
}
private string GetAuthorityUrl()
{
return $"{LoginUrl}/{TenantId}";
}
public async Task<OrganizationWebProxyClient> CreateClient()
{
var context = new AuthenticationContext(GetAuthorityUrl(), false);
var token = await context.AcquireTokenAsync(GetResourceUrl(), new ClientCredential(ClientId, ClientSecret));
return new OrganizationWebProxyClient(new Uri(GetServiceUrl()), true)
{
HeaderToken = token.AccessToken,
SdkClientVersion = "9.1"
};
}
public async Task<OrganizationServiceContext> CreateContext()
{
var client = await CreateClient();
return new OrganizationServiceContext(client);
}
public async Task TestApiCall()
{
var context = await CreateContext();
// send a test request to verify authentication is working
var response = (WhoAmIResponse) context.Execute(new WhoAmIRequest());
}
}
With Microsoft Dynamics CRM Online or internet facing deployments
When you use the Web API for CRM Online or an on-premises Internet-facing deployment (IFD)
you must use OAuth as described in Connect to Microsoft Dynamics CRM web services using OAuth.
Before you can use OAuth authentication to connect with the CRM web services,
your application must first be registered with Microsoft Azure Active Directory.
Azure Active Directory is used to verify that your application is permitted access to the business data stored in a CRM tenant.
// TODO Substitute your correct CRM root service address,
string resource = "https://mydomain.crm.dynamics.com";
// TODO Substitute your app registration values that can be obtained after you
// register the app in Active Directory on the Microsoft Azure portal.
string clientId = "e5cf0024-a66a-4f16-85ce-99ba97a24bb2";
string redirectUrl = "http://localhost/SdkSample";
// Authenticate the registered application with Azure Active Directory.
AuthenticationContext authContext =
new AuthenticationContext("https://login.windows.net/common", false);
AuthenticationResult result =
authContext.AcquireToken(resource, clientId, new Uri(redirectUrl));
P.S: Concerning your method, it is a best practice to not to store the password as clear text, crypt it, or encrypt the configuration sections for maximum security.
See walkhrough here
Hope this helps :)
If I understand your question correctly, you want to connect to Dynamics 2016 (Dynamics 365) through a Registerd Azure Application with ClientId and Secret, instead of Username and Password. If this is correct, yes this is possible with the OrganizationWebProxyClient . You can even use strongly types assemblies.
var organizationWebProxyClient = new OrganizationWebProxyClient(GetServiceUrl(), true);
organizationWebProxyClient.HeaderToken = authToken.AccessToken;
OrganizationRequest request = new OrganizationRequest()
{
RequestName = "WhoAmI"
};
WhoAmIResponse response = organizationWebProxyClient.Execute(new WhoAmIRequest()) as WhoAmIResponse;
Console.WriteLine(response.UserId);
Contact contact = new Contact();
contact.EMailAddress1 = "jennie.whiten#mycompany.com";
contact.FirstName = "Jennie";
contact.LastName = "White";
contact.Id = Guid.NewGuid();
organizationWebProxyClient.Create(contact);
To get the AccessToken, please refer to the following post Connect to Dynamics CRM WebApi from Console Application.
Replace line 66 (full source code)
authToken = await authContext.AcquireTokenAsync(resourceUrl, clientId, new Uri(redirectUrl), new PlatformParameters(PromptBehavior.Never));
with
authToken = await authContext.AcquireTokenAsync( resourceUrl, new ClientCredential(clientId, secret));
You can also check the following Link Authenticate Azure Function App to connect to Dynamics 365 CRM online that describes how to secure your credentials using the Azure Key Vault.
In Sharepoint 2010, clicking "Site Actions"--> "Site Permission" --> "Check Permissin", you can get permission by user. How can I do the same thing using sharepoint API in c#?
The method "GetUserEffectivePermissionInfo" server users only.
If the permissions need to find a group, just do this:
using (SPSite site = new SPSite("/"))
{
using (SPWeb web = site.OpenWeb())
{
SPGroup spGroupItem = web.Groups["GroupName"];
SPRoleAssignment oRoleAssignment = web.RoleAssignments.GetAssignmentByPrincipal(spGroupItem);
foreach (SPRoleDefinition inRole in oRoleAssignment.RoleDefinitionBindings)
{
//inRole.id //inRole.Name
//1073741829 //limited access
}
}
}
Try SPWeb.GetUserEffectivePermissionInfo
Gets the effective permissions that the specified user has and the role assignments related to this user within this scope.