I developed a script to retrieve list items form a SharePoint Online server that works perfectly fine on my Windows 10 notebook, but not on a default Windows Server 2012 R2 instance. Here is the relevant code:
$context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$context.RequestTimeout = 360000
$context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)
$list = $Context.Web.Lists.GetByTitle($ListTitle)
$qry = new-object Microsoft.SharePoint.Client.CamlQuery
$camlString = "somequery"
$qry.ViewXml = $camlString
$items = $list.GetItems($qry)
$Context.Load($items)
$Context.ExecuteQuery()
Unfortunately, the $list variable does not get any lists back from SharePoint on the 2k12 R2 server and therefore I get the following error in the end.
Exception calling "ExecuteQuery" with "0" argument(s): "Value cannot be null.
Parameter name: key"
At E:\temp\MDS_SharepointTracker_v2.ps1:131 char:5
+ $Context.ExecuteQuery()
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentNullException
I am pretty sure that it has something to do with the authentication, but I am not able to figure out what.
The credentials used for login are the same on both systems, both systems have the SharePoint Online Management Shell installed, Powershell version is the same and the DLLs loaded (see below). Proxy settings are the same on both systems. Through the browser, I can access SharePoint Online on the server.
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")
Only difference is that I am logged in with a domain user on my notebook (although not from the same domain as the user used for SP credentials) and on the server, I am using a local user.
Anyone an idea or a hint?
After some more investigation I finally found the issue.
The server I was testing the script is not joined to a domain. Therefore, no trust is available between the server and SP online what causes the authentication to fail - although without any indication in that direction.
Examining $error[0]|format-list -force was what drove me to test on authentication issues.
Trying the script on different other clients and a domain-joined servers was successfully.
Although no more required, I couldn't find a way to be able to run the script on the workgroup server, SharePointOnlineCredentials does not seem to be able to handle login if no federation is in place...but correct me if I'm wrong
Related
Please help to solve the problem.
I have application. It calls SharePoint web-service List.asmx to get list elements.
Here the code:
Lists listService = new Lists();
NetworkCredential credentials = new NetworkCredential();
credentials.UserName = serviceUserName
credentials.Password = servicePassword;
credentials.Domain = domain;
listService.Credentials = credentials;
listService.Url = serviceUrl.ToString();
XmlDocument xmlDoc = new XmlDocument();
XmlNode nodeListItems = listService.GetListItems(categoryListName.ToString(), null, null, null, "10000", null, null);
The credentials user has access to the list site.
If I deploy application on any server, is's ok. I get elements of List. But if I deploy application one the same server with list site, I get an Error 401: Unauthorized.
How can I solve the problem? I realy need to deploy application on the same server.
A bit of research and I found the reason behind it.
The .Net 3.5 framework introduces a loop-back problem that affects web service authentication in SharePoint. This issue doesn’t allow web services to be accessed by any mode (client/tool/server). Microsoft decided to introduce this, but unfortunately it breaks a number of different things in SharePoint.
Hence a registry entry has to be created in the web front end servers to resolve the loop back issue.
Implementation
Perform below steps on each of the SharePoint Web Front End Servers.
Click Start, click Run, type regedit, and then click OK.
In Registry Editor, locate and then click the following registry key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
Right-click Lsa, point to New, and then click DWORD Value.
Type DisableLoopbackCheck, and then press ENTER.
Right-click DisableLoopbackCheck, and then click Modify.
In the Value data box, type 1, and then click OK.
Quit Registry Editor, and then restart your computer.
https://askmanisha.wordpress.com/2014/03/26/401-unauthorized-error-while-calling-a-web-service/
I'm getting blank pages when navigating the WSO2 ESB-4.9.0 management console. For example, the registry, templates, endpoints, and local entries pages are all blank when navigating to them in the console UI.
I've found the following errors in the logs:
Error during rendering
IO Error executing tag: JSPException while including path '/templates/list_templates.jsp'. ServletException while including page.
The ESB is running in a YAJSW Windows Service. I should note that the ESB runs fine when running straight from the command line, it's just when using the service wrapper.
Strainy
Since you mentioned that the ESB starts as a window service, in carbon 4.4.x, default wrapper.conf file needs to be updated with following additional entries.
wrapper.java.additional.26 = -Dwso2.carbon.xml=${carbon_home}\\repository\\conf\\carbon.xml
wrapper.java.additional.27 = -Dwso2.registry.xml=${carbon_home}\\repository\\conf\\registry.xml
wrapper.java.additional.28 = -Dwso2.user.mgt.xml=${carbon_home}\\repository\\conf\\user-mgt.xml
wrapper.java.additional.29 = -Dwso2.transports.xml=${carbon_home}\\repository\\conf\\mgt-transports.xml
wrapper.java.additional.31 = -Dorg.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING=false
wrapper.java.additional.33 = -Dfile.encoding=UTF8
You can verify these configurations in wrapper.conf and these configurations may help you to solve the jsp error.
Following link may help you if you need more information regarding this.
https://docs.wso2.com/display/ESB490/Installing+as+a+Windows+Service#InstallingasaWindowsService-SettinguptheYAJSWwrapperconfigurationfile
I just used the NSSM - the "Non-Sucking Service Manager".
It's actually amazingly simple to install a Service using this tool.
https://nssm.cc
Just set it up to point at the wso2server.bat file
Keeping an eye on this issue however: https://wso2.org/jira/browse/ESBJAVA-4342
How to assign to workers a proxy that requires user name - password and a custom user agent using Selenium, PhantomJS driver with Python bindings.
I've had good success with creating many workers traversing my test website. I can also assign a user agent or a proxy that does not require authorization. But I haven’t figured out how to do both to the same worker at the same time yet.
However the real issue at the moment is assigning a proxy to the workers that require authorization by a user name and password.
The Players:
Selenium 2.33.0 / PhantomJS 1.9.1 / Python 2.7.3 / Ubuntu 12.04
Me:
Nube. Python weeks, Linux days, Selenium hours, PhantomJS -= , SO first post
Searches Yielded:
How do I set a proxy for phantomjs/ghostdriver in python webdriver?
The answers may in fact be there and many other places I have read and re-read, but I can’t connect the dots at my present level.
User Agent solved with this method.
dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap["phantomjs.page.settings.userAgent"] = (
"Any User Agent string here”)
driver = webdriver.PhantomJS(desired_capabilities=dcap)
Proxy without authorization works with this:
service_args = [
'--proxy=127.0.0.1:9999',
'--proxy-type=http,
]
driver = webdriver.PhantomJS('/usr/local/bin/phantomjs,service_args=service_args)
If both above methods are used I’m unsure how to pass both proxy and UA to the PhantomJS driver. ATM I’m only able to do one or the other and not at all with a proxy that requires authorization.
Goal for this SO thread:
Learn how to assign a proxy that requires user name / password
Assign a custom user agent to the same worker.
Using Selenium, PhantomJS driver with Python bindings.
The end game goal is to assign each worker a unique ip and pull from a pool of user agents. Creating the logic for this I remain optimistic but the proxy with authorization is kicking me at the moment.
As you can tell I’m very new to all of this and would appreciate any help and examples to this particular problem.
Thanks!
EDIT: Below accepted answer is incorrect. Unable to reproduce below solution. Only the proxy with authorization is assigned to the driver. Still unable to assign both proxy and a user agent to the same driver.
Any help or direction would be greatly appreciated.
EDIT.02: Issue resolved. It was never a coding issue. A new proxy provider at the server level assigned a default UA that overrode the above script. Once this was removed all was good.
Assign User Agent by Desired Capabilities
dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap["phantomjs.page.settings.userAgent"] = (
"Your User Agent String here . . .")
Found API Reference here for the proxy authorization.
Add "--proxy-auth=username:password" to server_args. Like . . .
service_args = [
'--proxy=xxx.xxx.xx.xxx:xxxx',
'--proxy-auth=username:password',
'--proxy-type=http',
]
Then use both when starting the webdriver
driver = webdriver.PhantomJS(desired_capabilities=dcap,service_args=service_args)
This took care of all my issues.
EDIT: Unable to reproduce solution. Only proxy is changed with above method.
EDIT.02: Issue resolved. It was never a coding issue. A new proxy provider at the server level assigned a default UA that overrode the above script. Once this was removed all was good.
I am using the following form of the NetworkCredential constructor to set explicit credentials before invoking a webservice that requires a specific identity:
myWebService.Credentials = new System.Net.NetworkCredential(userName, password, domain);
This has been working fine in our IIS 6.0 development and IIS 7.5 staging environments where the various servers are part of our domain.
Now this code has been deployed to a production environment where the servers are NOT part of a domain but just members of a WORKGROUP and the proper authentication is not working. At runtime, this effective substitution is failing:
myWebService.Credentials = new System.Net.NetworkCredential("localuserName", "XyZ!XyZ", "myServerName");
I don't have complete access to these various workgroup machines and the sysadmin who configured things there appears to have set up the local accounts and application pools correctly.
So, in summary, can use of the above technique continue to work in a WORKGROUP by simply using the name of the server instead of the domain name? If the code should work in either case, then there must be some other configuration problem where I will have to chase down more information on the problem.
i'm using iis 7 and there is no problem with following:
1. find the ip address of machine which is running IIS and
find webservice bindings the bindings in IIS is like the following http://192.368.228.1:8051/
2. set domain like this : http://servername:port/ or http://machine-ip:port/
also you can set webservice url like the following
myWebService.Url ="http://192.368.228.1:8051/service1.asmx";
myWebService.Credentials = new System.Net.NetworkCredential("user", "pass");
no domain is used in this way.
for more information about this subjects have look on following link
this section: Passing Credentials for Authentication to Web Services
http://msdn.microsoft.com/en-us/library/ff649362.aspx#secnetch10_usingclientcertificates
hope this could be helpful.
I created a very simple webservice in ASP.NET 2.0 to query a list in SharePoint 2007 like this:
namespace WebService1
{
/// <summary>
/// Summary description for Service1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
[WebMethod]
public string ShowSPMyList()
{
string username = this.User.Identity.Name;
return GetList();
}
private string GetList()
{
string resutl = "";
SPSite siteCollection = new SPSite("http://localhost:89");
using (SPWeb web = siteCollection.OpenWeb())
{
SPList mylist = web.Lists["MySPList"];
SPQuery query = new SPQuery();
query.Query = "<Where><Eq><FieldRef Name=\"AssignedTo\"/><Value Type=\"Text\">Ramprasad</Value></Eq></Where>";
SPListItemCollection items = mylist.GetItems(query);
foreach (SPListItem item in items)
{
resutl = resutl + SPEncode.HtmlEncode(item["Title"].ToString());
}
}
return resutl;
}
}
}
This web service runs well when tested using the built-in server of Visual Studio 2008. The username indicates exactly my domain account (domain\myusername).
However when I create a virtual folder to host and launch this web service (still located in the same machine with SP2007), I got the following error when invoking ShowSPMyList() method, at the line to execute OpenWeb(). These are the details of the error:
System.Data.SqlClient.SqlException: Cannot open database "WSS_Content_8887ac57951146a290ca134778ddc3f8" requested by the login. The login failed.
Login failed for user 'NT AUTHORITY\NETWORK SERVICE'.
Does anyone have any idea why this error happens? Why does the web service run fine inside Visual Studio 2008, but not when running stand-alone? I checked and in both cases, the username variable has the same value (domain\myusername).
Thank you very much.
Thank you very much for the replies. I'll look into the documents to see how i can change the settings related to the application pool as suggested.
I want to make clear that i wanted to build a webservice to run outside of sharepoint (but can be deployed on the same server with sharepoint).
Is there any way i can programmatically pass the credentials (another domain account instead of 'NT AUTHORITY\NETWORK SERVICE' by default) to sharepoint when invoking OpenWeb method? I believe if i'm able to do that then i can walkaround the security issue above.
When you create your own custom virtual folder and set it inside the IIS, it's highly possible that the user account who run the application pool of that particular IIS virtual directory is currently set to NT authority\Network Service.
You can check carefully, by looking closely of what is the actual application pool that run that particular IIS virtual directory.
From there, you can go to the "Application Pool" folder and right click, choose Properties. Select the "Identity" tab, and it will show you who is the user account that currently running the application pool.
Alternatively, you can refer to the SharePoint SDK, something similar to ExtractCrmAuthenticationToken in dynamics CRM to extract the Authentication Token ticket.
Or alternatively you can use Network Credential to embed your own custom user id and password.
Hope this helps,
hadi teo
I fully agree with Hadi, if this is something you want to just quickly test, for a proof of concept, you can change the credentials under what the Application pool runs, to a user that has permissions. Or you could use Identity Impersonate setting in your config file.
However resist the temptiation to do this in a production enviroment, use the proper authentication. It will come back, to bite you.
If you need to set this up for production, there is a couple of areas that you want to look at, duplicate SPN's, and deligation probably the most common areas that is not configured correctly. Your error however points to impersanation not happening.
Also make sure you are deploying the web service to its own web site that does not already run SharePoint. If you want the web service to run on the same web site as SharePoint read Creating a Custom Web Service.
You can check what application pool identity SharePoint is using by following the same instructions that Hadi writes, but for an app pool running SharePoint. Make sure to only change the application pool used by your web service and not SharePoint or else other permission errors could occur within SP. (There should be no reason but if you are interested in changing the app pool identity used by SharePoint follow these instructions.)
On solution would be to "impersonate" as the SharePoint System account using the following code:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
// also dispose SPSite
using (SPSite siteCollection = new SPSite("http://localhost:89"))
{
using (SPWeb web = siteCollection.OpenWeb())
{
// ...
}
}
});