Editing SharePoint2010 List from Out side windows app. - web-services

Actually I am trying to add items in a share point List from a windows application. It all goes fine when I added the web reference and the able to get the all the offerings listed for Lists.asmx.
When I execute my program and try to call listServiceObj.GetListAndview("Customers","");
It gives me error "The request failed with HTTP status 401: Unauthorized" . Please note that at this time my credentials and url of the service reference were;
SpListService.Lists spListService = new SpListService.Lists();
spListService.Credentials = System.Net.CredentialCache.DefaultCredentials;
spListService.Url = "http://localhost/_vti_bin/Lists.asmx";
XmlNode customerListView = spListService.GetListAndView("Customers", "");
Then I Changed the above code to ;
SpListService.Lists spListService = new SpListService.Lists();
spListService.Credentials = System.Net.CredentialCache.DefaultCredentials;
spListService.Url = "http://<PC-Name>/sites/Home/_vti_bin/Lists.asmx";
XmlNode customerListView = spListService.GetListAndView("Customers", "");
then I recieved the following error;
"Exception of type 'Microsoft.SharePoint.SoapServer.SoapServerException' was thrown."
I have made the logged in user in the group of full controll. also the member of the Administrator group.. but same result....
Also please note that when try and access "http://localhost/" or "http:///" it gives me access denied page of SP2010.... instead I have to write "http:///sites/Home/SitePages/Home.aspx" to open my team site collection
I really stuck in to this .... would be really pleased to have some solution to this problem of mine...... Thanks in advance
MJay

I had a similar problem when I implemented my first SharePoint lists Web Service client. The reason was that the autogenerated client class actually introduced itself as a Mozilla web browser by default! The SharePoint server did not allow basic authentication for browsers so the client was actually redirected to firewall login page.
I suggest you to inherit another class from the Lists class and do the following:
Set another user agent value in constructor.
Set the "preauthenticate" property to true. This should force the client to send the credentials in the first request, not only after they have been asked for.
If necessary, try giving the credentials explicitly.
See the example below.
public class CustomizedLists : Lists
{
public CustomizedLists() : base()
{
this.UserAgent = "Some SharePoint client";
this.PreAuthenticate = true;
System.Net.ICredentials creds = new System.Net.NetworkCredential("user", "pwd");
this.Credentials = creds.GetCredential(uri, "Basic");
}
}

Related

SharePoint web-service. Error 401: Unauthorized

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/

How to attach X509Certificate2 to webservice (Apple GSX / C# specific)

Apple released their New Generation WSDL on the 15 of August this year (2015) and the big change was that every call to the WSDL had to be validated with a certificate file.
I've done the process to get the certificate from Apple, and I've whitelisted our server IP, and I've even verified that I can get access to the service endpoint from our server by coding a simple interface using HttpWebRequest where I easily can attach the certificate using webRequest.ClientCertificates.Add(), so I know everything is ready for it to work.
But, my problem arises when I download the WSDL from https://gsxwsut.apple.com/apidocs/prod/html/WSArtifacts.html?user=asp
I import the WSDL into Visual Studio and when I try to make an instance of the client class, the only one I find is GsxWSEmeaAspPortClient, which seems to be correct as it has all the functions for authenticate and various tools, but it does not have ClientCertificates. It does have ClientCredentials which have ClientCertificate, but when I try to set the cert there, it's as tho it's never set.
I'm guessing the service code transmits the data via either HttpWebRequest or WebRequest, so if I just can get to the request code from my instance of the class (GsxWSEmeaAspPortClient) I can probably fix it, but I can't seem to get there.
I've looked at this question: How can I connect with Apple's GSX NewGeneration webservices with WCF? which suggests it really should be that easy, but I don't have the GsxWSEmeaAspService, only the GsxWSEmeaAspPortClient from my Visual Studio's generation of the WSDL.
If anyone has any ideas which can point me in any direction towards victory I'd be eternally grateful.
I'm using Visual Studio 2013 and the solution is .Net v4.5.1 if that makes any difference.
I've pasted new code here:
public void Authenticate() {
// Use custom binding with certificate authentication
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
// Create service endpoint
// Use proper endpoint address - eg. gsxapi.apple.com for production
EndpointAddress endpoint = new EndpointAddress("https://gsxapiit.apple.com/gsx-ws/services/emea/asp");
// Create new service
Apple.GsxWSEmeaAspPortClient service = new Apple.GsxWSEmeaAspPortClient(binding, endpoint);
// Set loaded certificate
service.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(
"[PathToContainerFromStep7].p12",
"[YourPasswordFromStep8]");
// Create authenticate request object
Apple.authenticateRequestType auth = new Apple.authenticateRequestType()
{
languageCode = "en",
userId = "[YourAppleServiceAccountNumber]",
userTimeZone = "[YourTimeZone]",
serviceAccountNo = "[YourSoldToNumber]"
};
// Authenticate to Apple GSX
Apple.authenticateResponseType session = service.Authenticate(auth);
// Assign your new session id object
userSessionId = new Apple.gsxUserSessionType() { userSessionId = session.userSessionId };
}

RESTEasy Client Proxy Preemptive Basic Authentication

I am using RESTEasy Proxy Framework to call my Rest-Services. I would like to use preemptive authentication with the proxy framework.
Thats my current Code:
public void callSomeService() throws Exception {
RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
DefaultHttpClient client = new DefaultHttpClient();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(
USERNAME, PASSWORD);
AuthScope authscope = new AuthScope(AuthScope.ANY_HOST,
AuthScope.ANY_PORT, AuthScope.ANY_REALM);
client.getCredentialsProvider().setCredentials(authscope, credentials);
ApacheHttpClient4Executor executer = new ApacheHttpClient4Executor(client);
dummyResource = ProxyFactory.create(DummyResource.class,
"http://localhost:8888/myapp/rest/", executer);
// Do some calls here
}
When I monitor the traffic of my application, the Rest-Service gets called twice:
First the client receives an 401 Error (UNAUTHORIZED)
In the second request there is the Authorization Header added and everything works
fine.
What I actually want to do is that the Authorization Header is already added in the first request! How can I do that?
I am using RESTEasy 2.3.5! I also read the documentation (http://docs.jboss.org/resteasy/docs/2.3.5.Final/userguide/html_single/index.html#transport_layer) where is an example given for preemptive authentication, which actually doesnt work, because of this code:
BasicScheme basicAuth = new BasicScheme();
authCache.put("com.bluemonkeydiamond.sippycups", basicAuth);
You're right, the example in the documentation does not compile. Try replacing the string "com.bluemonkeydiamond.sippycups" with an instance of HttpHost. The HttpHost class has several constructors so be sure to look at the JavaDocs. The simplest constructor takes a string. For example,
BasicScheme basicAuth = new BasicScheme();
authCache.put(new HttpHost("com.bluemonkeydiamond.sippycups"), basicAuth);

Basic Authentication with embedded Jetty 7 server and no web.xml file

I have an embedded implementation of Jetty 7 running as a service and want to add basic authentication with no web.xml file for a servlet.
I created my credentials using the steps described here
I thought that I could create the server, create a security handler with basic authentication and attach a HashLoginService to the security manager. But I am clearly missing several things because I am never getting prompt for credentials.
Below is the code. Any help would be greatly appreciated.
server = new Server(port);
server.addConnector(getSslChannelConnector(securePort));
server.setGracefulShutdown(1000);
server.setStopAtShutdown(true);
// create the context handler for the server
ServletContextHandler sch = new ServletContextHandler(server, WEBAPP_CONTEXT);
// attach the security handler to it that has basic authentication
sch.setSecurityHandler(getSecurityHandler());
// define the processing servlet.
sch.addServlet(new ServletHolder(new ProcessingServlet()), "/process");
.
.
private SecurityHandler getSecurityHandler() {
// add authentication
Constraint constraint = new Constraint(Constraint.__BASIC_AUTH,"user");
constraint.setAuthenticate(true);
constraint.setRoles(new String[]{"user","admin"});
// map the security constraint to the root path.
ConstraintMapping cm = new ConstraintMapping();
cm.setConstraint(constraint);
cm.setPathSpec("/*");
// create the security handler, set the authentication to Basic
// and assign the realm.
ConstraintSecurityHandler csh = new ConstraintSecurityHandler();
csh.setAuthenticator(new BasicAuthenticator());
csh.setRealmName(REALM);
csh.addConstraintMapping(cm);
// set the login service
csh.setLoginService(getHashLoginService());
return csh;
}
private HashLoginService getHashLoginService() {
// create the login service, assign the realm and read the user credentials
// from the file /tmp/realm.properties.
HashLoginService hls = new HashLoginService();
hls.setName(REALM);
hls.setConfig("/tmp/realm.properties");
hls.setRefreshInterval(0);
return hls;
}
I got this working and posted a sample webapp here
The code looks broadly ok.
My interface is slightly different for adding the ConstraintMapping as the single CM add seems have gone in my version of jetty 7.
securityHandler.setConstraintMappings(new ConstraintMapping[] {cm});
Bar that my code is basically identical and does work for me.
Note that once authenticated your browser will not prompt you again unless you restart your browser or follow the instructions here

Login failed when a web service tries to communicate with SharePoint 2007

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())
{
// ...
}
}
});