C# CSOM Sharepoint Access with Tokens - c#

I have been really struggling with getting Access Tokens working with our Sharepoint site and still no luck.
The problem is when I access our site using the SharepointOnlineCredentials it works fine, well I can query the sharepoint as follows and this works but I want to use the new token stuff that just doesn't work for me
using (ClientContext context = new ClientContext(sharepointSiteUrl))
{
context.Credentials = GetCredentials();
var web = context.Web;
context.Load(web, w => w.Title);
context.ExecuteQuery();
if (context.Web.IsPropertyAvailable("Title"))
{
Console.WriteLine("Found title");
}
Console.WriteLine("Title: {0}", web.Title);
}
private static SharePointOnlineCredentials GetCredentials()
{
SecureString password = new SecureString();
foreach (char c in "MyPassword".ToCharArray()) password.AppendChar(c);
return new SharePointOnlineCredentials("myname#mycompany.com", password);
}
So now for the code that doesn't work
authContext = new AuthenticationContext(authority, new FileCache());
ClientCredential clientCredentials = new ClientCredential(clientId, clientSecret);
AuthenticationResult authenticationResult = authContext.AcquireToken(resource, clientCredentials);
Console.WriteLine("Token Type: {0} \nExpires: {1} \nToken: {2}", authenticationResult.AccessTokenType, authenticationResult.ExpiresOn, authenticationResult.AccessToken);
using (ClientContext context = TokenHelper.GetClientContextWithAccessToken(sharepointSiteUrl, authenticationResult.AccessToken))
{
var web = context.Web;
context.Load(web);
context.ExecuteQuery();
if (context.Web.IsPropertyAvailable("Title"))
{
Console.WriteLine("Found title");
}
Console.WriteLine("Title: {0}", web.Title);
}
Now when I run this the web.Title throws an error and the context.Web display 'Cannot find the method on the object instance.'
The web.Title in the debugger also states 'The property or field 'Title' has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.'
I really would love some help with this as it's turned impossible for me. Thanks :)
Do I need to be aware or granting access somewhere else? as its strange that the first one works!

In the first example you are explicitly requesting the Title property from the CSOM end-point:
context.Credentials = GetCredentials();
var web = context.Web;
context.Load(web, w => w.Title); // explicitly requesting the Title property
context.ExecuteQuery();
Whereas in the second example there is no context.Load(web, w => w.Title);
Maybe this is the issue?

Related

Microsoft.SharePoint.Client.IdcrlException: 'The sign-in name or password---' Even WITH Pnp Authentication Manager

I have signed up for the Office 365 Developer Edition with Microsoft 365 E5 Developer (without Windows and Audio Conferencing). I am writing codes to connect to the Sharepoint of developer domain. Following are my codes:
public static String GetList( ICredentials credentials)
{
var authManager = new OfficeDevPnP.Core.AuthenticationManager();
using (ClientContext clientContext =
authManager.GetWebLoginClientContext("https://xxx.sharepoint.com"))
{
clientContext.Credentials = credentials;
Web web = clientContext.Web;
clientContext.Load(web,
webSite => webSite.Title);
clientContext.ExecuteQuery();
return web.Title;
}
}
public string callSharepoint()
{
const string userName = "Username#domain.onmicrosoft.com";
const string password = "xxxx";
var securePassword = new SecureString();
foreach (var c in password)
{
securePassword.AppendChar(c);
}
var credentials = new SharePointOnlineCredentials(userName, securePassword);
var list = GetList(credentials);
return list.ToString();
}
While running, it first asks to enter Microsoft Office credentials, and then it does verification by sending code to contact number and then after verification is completed it throws an Exception on Line
clientContext.ExecuteQuery(). The Exception is as follow:
Microsoft.SharePoint.Client.IdcrlException: 'The sign-in name or password does not match one in the Microsoft account system.'
The credentials I am using is of Admin Account with role Global Administrator. I also tried to add new user account in that Active Directory and tried that credentials but still got the same exception on the same place.
I even try to remove Pnp Authorization, Enable and disable Multi factor Authorization, but no success. However, I can successfully log in into the Sharepoint site on browser by using exactly same credentials.
What I think is, there is most likely a problem in the setup which I did while setting office account developer subscription. And maybe nothing is wrong with the code because I used the same codes to log in to my organization's Sharepoint and it works perfectly fine. Maybe I need something else to be configured in my developer's Office Account.
Please let me know if anyone already has some knowledge about this problem.
You have init the credential so you could use it directly, if issue exists, should be related to your user account or license.
public static String GetList(ICredentials credentials)
{
//var authManager = new OfficeDevPnP.Core.AuthenticationManager();
//using (ClientContext clientContext =
//authManager.GetWebLoginClientContext("https://xxx.sharepoint.com/sites/lee"))
//{
//}
using (ClientContext clientContext = new ClientContext("https://xxx.sharepoint.com/sites/lee"))
{
clientContext.Credentials = credentials;
Web web = clientContext.Web;
clientContext.Load(web,
webSite => webSite.Title);
clientContext.ExecuteQuery();
return web.Title;
}
}
public string callSharepoint()
{
const string userName = "user#xxx.onmicrosoft.com";
const string password = "password";
var securePassword = new SecureString();
foreach (var c in password)
{
securePassword.AppendChar(c);
}
var credentials = new SharePointOnlineCredentials(userName, securePassword);
var list = GetList(credentials);
return list.ToString();
}
Ok I found the solution.
That is I don't need this line of code:
clientContext.Credentials = credentials;
Since MFA is enabled, so when I logged in via Pnp Authenticator, it should use that user account. Instead of the one which is passed via SharePointOnlineCredentials.

How to fix 'operation has timed out' while connecting to sharepoint on Office 365 using C#

"Operation has timed out" error while connecting to Office 365 Sharepoint from asp.net web application
I have tried finding answers and implementing solutions like below:
How to connect to SharePoint on Office 365 with CSOM from C#?
Also some blogs suggested making an asynchronous query, which does not throw error but also does not give any results.
Also tried setting timeout property without any help.
Below is my code:
SharePointOnlineCredentials networkCredential = new
SharePointOnlineCredentials(SharePointUser, SharePointPassword);
Context = new ClientContext(SharePointURL);
Context.Credentials = networkCredential;
Web = Context.Web;
Context.Load(Web);
Context.ExecuteQuery();`
Also, strangely I am able to connect and get data using Console application, but I need to get this working in web application.
After a lot of search I realized that we need proxy to connect to Sharepoint Online and implemented following code to achieve
clientContext.ExecutingWebRequest += (s, e) =>
{
e.WebRequestExecutor.WebRequest.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
};
Add clientContext.RequestTimeout = -1 in the code, the code below for your reference.
string siteUrl = "https://tenant.sharepoint.com/sites/lz";
string userName = "lz#tenant.onmicrosoft.com";
string password = "xxx";
var securePassword = new SecureString();
foreach (char c in password.ToCharArray()) securePassword.AppendChar(c);
using (ClientContext clientContext = new ClientContext(siteUrl))
{
clientContext.Credentials = new SharePointOnlineCredentials(userName, securePassword);
clientContext.RequestTimeout = -1;
var web = clientContext.Web;
clientContext.Load(web);
clientContext.ExecuteQuery();
}

AADSTS500011 - PowerBi C# .NET (resource x not found in tenant y)

I am trying to integrate the power bi embedded with C#, I always have this same error that comes out, I put it to you just below, as well as the versions of the packages and the code (basic) which is supposed to do the work .
Thank you for all your answers
Microsoft.PowerBI.Api (v2.0.12)
Microsoft.PowerBI.JavaScript (v2.5.1)
Microsoft.IdentityModel.Clients.ActiveDirectory (v3.13.9)
Microsoft PowerBI JavaScript (v2.5.1)
Microsoft IdentityModel Clients.ActiveDirectory (v3.13.9)
Note that the two head variables are temporary.
The error always come out at this line : var authenticationResult = await authenticationContext.AcquireTokenAsync(this.resourceUrl, this.applicationId, credential);
There is the error message : "exceptionMessage": "AADSTS500011: The resource principal named https://analysis.windows.net/powerbi/api/ was not found in the tenant named x. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.
public async Task<EmbedConfigResource> EmbedReport([FromUri]string username, [FromUri]string roles)
{
roles = "None";
username = this.pbiUsername;
var result = new EmbedConfigResource { Username = username, Roles = roles };
var credential = new UserPasswordCredential(this.pbiUsername, this.pbiPassword);
var authenticationContext = new AuthenticationContext(this.authorityUrl);
var authenticationResult = await authenticationContext.AcquireTokenAsync(this.resourceUrl, this.applicationId, credential);
var tokenCredentials = new TokenCredentials(authenticationResult.AccessToken, "Bearer");
using (var client = new PowerBIClient(new Uri(this.apiUrl), tokenCredentials))
{
var reports = await client.Reports.GetReportsInGroupAsync(this.workspaceId);
Report report = reports.Value.FirstOrDefault(r => r.Id == this.reportId);
var datasets = await client.Datasets.GetDatasetByIdInGroupAsync(this.workspaceId, report.DatasetId);
result.IsEffectiveIdentityRequired = datasets.IsEffectiveIdentityRequired;
result.IsEffectiveIdentityRolesRequired = datasets.IsEffectiveIdentityRolesRequired;
GenerateTokenRequest generateTokenRequestParameters;
var rls = new EffectiveIdentity(this.pbiUsername, new List<string> { report.DatasetId });
if (!string.IsNullOrWhiteSpace(roles))
{
var rolesList = new List<string>();
rolesList.AddRange(roles.Split(','));
rls.Roles = rolesList;
}
generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view", identities: new List<EffectiveIdentity> { rls });
var tokenResponse = await client.Reports.GenerateTokenInGroupAsync(this.workspaceId, report.Id, generateTokenRequestParameters);
result.EmbedToken = tokenResponse;
result.EmbedUrl = report.EmbedUrl;
result.Id = report.Id;
return result;
}
}
You must log into Azure portal, go to Azure Active Directory -> App registrations, select your app, click View API permissions, and then grant admin consent by clicking the button at the bottom:
If you don't have access to the portal, or the button is disabled, you must ask your admin to do it for you.

denyandaddcustomizedpages - modify the property using csom for modern team site

Currently we are using modern team site and trying to add the add the object on the modern team site in SharePoint online
However we observed that we get Access denied error
We tried by setting the site property denyandaddcustomizedpages to false from powershell and it is working fine
However we are not able to get the code which can help us achieve the same using csom client side object model SharePoint online c#
Few articles mention try using pnp nugget but no code was able to find for the same
You can do that using the below sample code.
Do note, executing this code requires SharePoint admin privileges, do make the necessary modifications as per your requirements:
var tenantAdminSiteUrl = "https://tenant-admin.sharepoint.com";
var siteCollectionUrl = "https://tenant.sharepoint.com/sites/Test";
var userName = "admin#tenant.onmicrosoft.com";
var password = "password";
using (ClientContext clientContext = new ClientContext(tenantAdminSiteUrl))
{
SecureString securePassword = new SecureString();
foreach (char c in password.ToCharArray())
{
securePassword.AppendChar(c);
}
clientContext.AuthenticationMode = ClientAuthenticationMode.Default;
clientContext.Credentials = new SharePointOnlineCredentials(userName, securePassword);
var tenant = new Tenant(clientContext);
var siteProperties = tenant.GetSitePropertiesByUrl(siteCollectionUrl, true);
tenant.Context.Load(siteProperties);
tenant.Context.ExecuteQuery();
siteProperties.DenyAddAndCustomizePages = DenyAddAndCustomizePagesStatus.Disabled;
var operation = siteProperties.Update();
tenant.Context.Load(operation, op => op.IsComplete, op => op.PollingInterval);
tenant.Context.ExecuteQuery();
// this is necessary, because the setting is not immediately reflected after ExecuteQuery
while (!operation.IsComplete)
{
Thread.Sleep(operation.PollingInterval);
operation.RefreshLoad();
if (!operation.IsComplete)
{
try
{
tenant.Context.ExecuteQuery();
}
catch (WebException webEx)
{
// catch the error, something went wrong
}
}
}
}

using google oauthutill in a desktop application to retrieve contacts

I am using oauth to get acces to google contacts from a desktop application. I have followed the instruction from google here: http://code.google.com/intl/iw-IL/apis/gdata/docs/auth/oauth.html#Examples but I am having problems
here is the code:
OAuthParameters parameters = new OAuthParameters()
{
ConsumerKey = CONSUMER_KEY,
ConsumerSecret = CONSUMER_SECRET,
Scope = SCOPE,
Callback = "http://localhost:10101/callback.htm.txt",
SignatureMethod = "HMAC-SHA1"
};
OAuthUtil.GetUnauthorizedRequestToken(parameters);
string authorizationUrl = OAuthUtil.CreateUserAuthorizationUrl(parameters);
Console.WriteLine(authorizationUrl);
var win = new GoogleAuthenticationWindow(authorizationUrl,parameters);
win.ShowDialog();
OAuthUtil.GetAccessToken(parameters);
inside the window I have the following:
private void BrowserNavigated(object sender, NavigationEventArgs e)
{
if (e.Uri.ToString().Contains("oauth_verifier="))
{
OAuthUtil.UpdateOAuthParametersFromCallback(e.Uri.ToString(), m_parameters);
Close();
}
}
at the last line (OAuthUtil.GetAccessToken(parameters);) I am getting a 400 bad request error and I have no idea why...
After much playing around... I think this is the easiest way to access google api:
Service service = new ContactsService("My Contacts Application");
service.setUserCredentials("mail#gmail.com", "password");
var token = service.QueryClientLoginToken();
service.SetAuthenticationToken(token);
var query = new ContactsQuery(#"https://www.google.com/m8/feeds/contacts/mail#gmail.com/full?max-results=25000");
var feed = (ContactsFeed)service.Query(query);
Console.WriteLine(feed.Entries.Count);
foreach (ContactEntry entry in feed.Entries)
{
Console.WriteLine(entry.Title.Text);
}
much easier than using oauth...

Categories

Resources