Motivation:
As we can read in Project Server Architecture
The SOAP-based ASMX interface for web services in the PSI is still available in Project Server 2013, but is deprecated.
As-Is
I have some PowerShell client snippets that I use to interact with Project Server. The standard way to communicate with the server are PSI ASMX web services.
To-Be
I would like to refactor the snippets to the standard of using PSI WCF web services.
Result
For example the following simple code works fine:
$Passwd = Get-Content $home\Documents\Password.txt | ConvertTo-SecureString
$Credential = New-Object -typename System.Management.Automation.PsCredential -argumentlist "user_name",$Passwd
$PWAUrl = "http://project_server_name/PWA"
$ProjSvcURL = $PWAUrl + "/_vti_bin/PSI/Project.asmx?wsdl"
$ProjSvcProxy = New-WebServiceProxy -uri $ProjSvcURL -credential $Credential
$projDataSet = $ProjSvcProxy.ReadProjectList()
$projDataSet.Tables[0].Rows.Count
but the simple conversion:
$Passwd = Get-Content $home\Documents\Password.txt | ConvertTo-SecureString
$Credential = New-Object -typename System.Management.Automation.PsCredential -argumentlist "user_name",$Passwd
$PWAUrl = "http://project_server_name/PWA"
$ProjSvcURL = $PWAUrl + "/_vti_bin/PSI/ProjectServer.svc"
...
fails with the message:
New-WebServiceProxy : The request failed with HTTP status 400: Bad Request.
Here is IIS log excerpt:
2014-01-05 13:50:41 10.15.43.7 GET /PWA/_vti_bin/PSI/ProjectServer.svc - 80 - XXX.XXX.XXX.XXX Mozilla/4.0+(compatible;+MSIE+6.0;+MS+Web+Services+Client+Protocol+2.0.50727.5472) 401 1 2148074254 125
2014-01-05 13:50:41 10.15.43.7 GET /PWA/_vti_bin/PSI/ProjectServer.svc - 80 - XXX.XXX.XXX.XXX Mozilla/4.0+(compatible;+MSIE+6.0;+MS+Web+Services+Client+Protocol+2.0.50727.5472) 401 2 5 328
2014-01-05 13:50:41 10.15.43.7 GET /_vti_bin/PSI/ProjectServer.svc/ntlm - 80 user_name XXX.XXX.XXX.XXX Mozilla/4.0+(compatible;+MSIE+6.0;+MS+Web+Services+Client+Protocol+2.0.50727.5472) 400 0 0 140
2014-01-05 17:58:33 10.15.43.7 GET /PWA/_vti_bin/PSI/ProjectServer.svc - 80 - XXX.XXX.XXX.XXX Mozilla/4.0+(compatible;+MSIE+6.0;+MS+Web+Services+Client+Protocol+2.0.50727.5472) 401 2 5 312
2014-01-05 17:58:33 10.15.43.7 GET /PWA/_vti_bin/PSI/ProjectServer.svc - 80 - XXX.XXX.XXX.XXX Mozilla/4.0+(compatible;+MSIE+6.0;+MS+Web+Services+Client+Protocol+2.0.50727.5472) 401 1 2148074254 156
2014-01-05 17:58:33 10.15.43.7 GET /_vti_bin/PSI/ProjectServer.svc/ntlm - 80 user_name XXX.XXX.XXX.XXX Mozilla/4.0+(compatible;+MSIE+6.0;+MS+Web+Services+Client+Protocol+2.0.50727.5472) 400 0 0 109
It is interesting that I cannot find any examples of using WCF PSI with PowerShell.
Have anyone tried to do this?
Have anyone succeed?
Can anyone publish any snippet?
I just had the same Problem as you do. Project Server Scripts using the asmx and wanting to port them to the WCF Service pendants.
After some digging I found the following MSDN Site:
http://msdn.microsoft.com/en-us/library/office/ms488627(v=office.15).aspx#pj15_PSIRefOverview_PSI
On there you got this Picture, shedding some light onto the whole WCF SVC thing: They are there, just not where you would expect them to be...
https://app.box.com/s/tsi7150bgra3rpg4n6yu
I tried to call the Service - and it worked like a charm.
I hope this helps you too!
P.S. Apologies for the box link... don't have enough reputation yet to post images ;)
Related
I actually a migrate an old asp .net framework 4 web app to asp .net core 6.
This webapp was serving docx et xlsx files through IIS and webdav to allow end users edit directly files on the server
On the old app, the config was like that
a virtual directory on IIS to associate a virtual Path Webdav to a physical path
an IHttpModule which allow me to intercept all request on the server and add some authentication when the request point out /webdav (webdav don't support anonymous authentication)
HttpContext.Request.Headers.Remove("Authorization");
HttpContext.Request.Headers.Add("Authorization", "Basic " + base64string);
On the new app
the virtual directory is manage directly on the code (Startup)
var lOptions = new FileServerOptions
{
FileProvider = new PhysicalFileProvider(Sys.Web.AppliIs.Path_Webdav),
RequestPath = new PathString("/" + Sys.Web.AppliIs.WEBDAV_FOLDER),
EnableDirectoryBrowsing = false,
};
app.UseFileServer(lOptions);
i intercept the request to add my authentication in a custom middleware (called before the code above)
app.Use(async (context, next) =>
{
AppliGeckosSL.WriteLogDebug($"intercept {context.Request.Path}, Method : {context.Request.Method}", null);//just to log everything which arrived
var lFileInfo = lHostEnv.ContentRootFileProvider.GetFileInfo(context.Request.Path);
if (lFileInfo != null)
{
WebdavFileManager.HandleRequest(context, lFileInfo.PhysicalPath);
}
// Call the next delegate/middleware in the pipeline.
await next(context);
});
Whe i test the new code (opening a file stored in the server with word), it failed.
Whe i inspect the logs, i notice thow things :
On the IIS logs, i see my different request called by word
2022-03-23 11:20:31 ::1 OPTIONS /Webdav/ - 7520 - ::1 Microsoft+Office+Protocol+Discovery 200 0 0 47
2022-03-23 11:20:31 ::1 HEAD /Webdav/BeWise.docx - 7520 - ::1 Microsoft+Office+Existence+Discovery 200 0 0 4
2022-03-23 11:20:31 ::1 OPTIONS /Webdav/ - 7520 - ::1 Microsoft+Office+Existence+Discovery 200 0 0 5
2022-03-23 11:20:31 ::1 LOCK /Webdav/BeWise.docx - 7520 - ::1 Microsoft+Office+Core+Storage+Infrastructure/1.0 405 0 0 4
2022-03-23 11:20:31 ::1 GET /Webdav/BeWise.docx - 7520 - ::1 Microsoft+Office+Core+Storage+Infrastructure/1.0 404 0 3 2
we can see the Lock method finished in 405
We can also see the get finishing in 404 which i can't understand because the HEAD finished on 200 on the same file
The log of my middleware give me only this
23/03 12:20:32:023 [FW] intercept /Webdav/BeWise.docx, Method : HEAD
23/03 12:20:32:055 [FW] intercept /Webdav/, Method : OPTIONS
so we see the LOCK and the GET are not handle by my server
I see many solutions on this problem on this forum and others which recommand to disable webdav, solution which dont fit me because i want to use webdav
There is not a lot of documentations about .net core and webdav, im not even sure its supported.
I try to remove the virtual directory by code and set a virtual directory through IIS like the old app but still not working, in this case the lock not finish in 405 but in 401. I notice my middleware in not called, so i cant add my authentication. I suppose with this option we don't go through the asp .net core pipeline.
What do you think ? any suggestion on that ?
Thanks for your help !
I had some answers from microsoft, the IIS webdav module is no longer supported with .net core (they will update the docs for that because it was not clearly said). So there is no way i will be able to achieve what i want.
My solutions now :
implement myself the webdav protocol
buy a licence to IT HIT WEBDAV Server Engine
thanks anyway for your answers, the subject is closed
I'm doing some password cracking experiments with different tools. I've a local set up within VMWare Workstation. I have a website protected by HTTP Basic Auth (A dialog pops up when i browse to it).
I'm struggling with the syntax of Patator though - I cant make it brute force the website (tools like Ncrack and Hydra worked OK). I have used it for SSH so i know the tool works, just can't figure the command for HTTP Basic Auth
patator http_fuzz auth_type=basic url=http://10.1.1.15 user_pass=FILE0:FILE0 0=./passwd_lists/user_pass.txt -x ignore:code=401
Where user_pass.txt contains a 'username':'password' separated by a colon
Basic Auth password is '123' and the user_pass.txt contain all permutations from 000 - 999, the username is consistent throughout. I can see Patator making 1000 attempts however they all fail with a HTTP 401
11:26:27 patator INFO - 401 672:456 0.001 | molly:969 | 970 | HTTP/1.1 401 Unauthorized
11:26:27 patator INFO - 401 672:456 0.001 | molly:979 | 980 | HTTP/1.1 401 Unauthorized
11:26:27 patator INFO - 401 672:456 0.001 | molly:989 | 990 | HTTP/1.1 401 Unauthorized
11:26:27 patator INFO - 401 672:456 0.001 | molly:999 | 1000 | HTTP/1.1 401 Unauthorized
11:26:28 patator INFO - Hits/Done/Skip/Fail/Size: 1000/1000/0/0/1000, Avg: 732 r/s, Time: 0h 0m 1s
I think i have the command syntax incorrect, any help really appreciated.
Thanks
Turns out i had the syntax incorrect, my user name and password were colon separated in one file, so the syntax should be
patator http_fuzz auth_type=basic url=http://10.1.1.15 user_pass=FILE0 0=./passwd_lists/user_pass.txt -x ignore:code=401
The difference being the single reference to to FILE0
I am trying to integrate mod_evasive with httpd on centos7. Module is installed and getting loaded by httpd upon restart. However, it is not picking up the parameters specified in /etc/httpd/conf.d/mod_evasive.conf file as specified below.
LoadModule evasive20_module modules/mod_evasive24.so
<IfModule mod_evasive24.c>
DOSHashTableSize 3097
DOSPageCount 20
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 10
DOSEmailNotify xyz#mail.com
DOSLogDir "/var/log/mod_evasive"
</IfModule>
I am testing the performance by one perl script as-
#!/usr/bin/perl
# test.pl: small script to test mod_dosevasive's effectiveness
use IO::Socket;
use strict;
for(0..300) {
my($response);
my($SOCKET) = new IO::Socket::INET( Proto => "tcp",
PeerAddr=> "172.31.19.247:80");
if (! defined $SOCKET) { die $!; }
print $SOCKET "GET /?$_ HTTP/1.0\n\n";
$response = <$SOCKET>;
print $response;
close($SOCKET);
}
Command executed by me is perl test.pl > sample.txt
In sample.txt, I'm getting HTTP/1.1 200 OK for first 120 requests and HTTP/1.1 403 Forbidden for all the remaining requests. But as per my understanding, the configuration set, It should have to start denying beyond 50 requests as specified in DOSSiteCount in mod_evasive.conf file. Am I missing something here?
I have a program written in VB.net that interacts with a data services hosted on IIS. Authentication is handled through the users Active Directory credentials. At one of my customer sites, on exactly one (out of about 100) of the customer's workstations, requests to the data service fail with status of 401.
Some additional relevant information: the production IIS installation is split into two nodes. A load balancer directs traffic to the nodes. Also, the exact same request made with Internet Explorer from workstation in question does not fail.
I suspect that something is stripping the user's credentials out of the requests when I make the request through the VB code, but I am stumped as to what that could be.
Here is the VB code that I use to make the request:
Dim httpRequest As HttpWebRequest = Nothing
Dim httpResponse As HttpWebResponse = Nothing
httpRequest = WebRequest.Create("http://server/xyzportal/portal.php")
httpRequest.KeepAlive = False
httpRequest.UseDefaultCredentials = True
httpRequest.Method = "GET"
httpRequest.ContentLength = 0
httpRequest.Accept = "text/xml"
httpRequest.Timeout = 3000000
httpResponse = httpRequest.GetResponse
Any thoughts would be appreciated.
Additional information: here are the IIS log entries for a request that fails. Notice the 2nd entry does not include the Windows user name:
2014-11-11 22:20:42 199.99.51.58 GET /xyzportal/portal.php - 80 - 199.99.50.128 - 401 2 5 0
2014-11-11 22:20:42 199.99.51.58 GET /xyzportal/portal.php - 80 - 199.99.50.128 - 401 1 2148074248 0
Contrast that to the IIS entries for a request from a working machine. Notice the 2nd entry does include the Windows user name:
2014-11-11 22:56:40 199.99.51.58 GET /xyzportal/portal.php - 80 - 199.99.50.128 - 401 2 5 0
2014-11-11 22:56:40 199.99.51.58 GET /xyzportal/portal.php - 80 MYDOMAIN\jreichert 199.99.50.128 - 200 0 0 93
The machine with the IP Address 199.99.50.128 is the load balancer.
I am logged in on the exact same domain and user on both machines.
You haven't said but if you are using a proxy then you haven't told the HttpRequest to use the AD user credentials for the proxy and so you are getting a 401 Unauthorised error, i.e. you are being refused access via the proxy. If so try this to explicitly tell it to...
HttpRequest.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials
I had exactly the same problem and it's solved it.
keepalive must be set to true. Setting keepalive = true fixes my problem. The following page explains the role of keepalive in the authentication handshake:
http://www.innovation.ch/personal/ronald/ntlm.html
I am still not sure why the request does not work on <1% of the workstations in my customer base when keepalive = false. All I know is setting keepalive = true makes the request work on 100% of the workstations.
More info: keepalive must be set to true when the authentication protocol is Kerebos. The request works if the authentication protocol is NTLM. I don't know why Kerebos gets used on only the two workstations where the request does not work.
is it possible to call a Methode of a WCF Service in a bat file. We want to test if the WCF Service works correct after the Server was restartet.
There are no commands within the BAT file universe that will allow you to contact a WCF service directly, however you could use a BAT file to run an existing console program that can connect and interact with a WCF service. So the answer is both yes and no; not directly, but through a separate program yes.
If you need some simple, clickable way of accessing a WCF service, I'd go with a Powershell or VB script (assuming you're in a windows environment).
Maybe you will be able to use PowerShell? It would be easier then. Create script with content:
$url = 'http://yoursite.url/example.svc'
$action = "`"http://some.namespace/method`""
$SOAPRequest = [xml]#'heregoesxmlmessage'#
write-host "Sending SOAP Request To Server: $url"
$soapWebRequest = [System.Net.WebRequest]::Create($url)
$soapWebRequest.Headers.Add("SOAPAction", $action)
$soapWebRequest.ContentType = "text/xml;charset=`"utf-8`""
$soapWebRequest.Accept = "text/xml"
$soapWebRequest.Method = "POST"
write-host "Initiating Send."
$requestStream = $soapWebRequest.GetRequestStream()
$SOAPRequest.Save($requestStream)
$requestStream.Close()
write-host "Send Complete, Waiting For Response."
$resp = $soapWebRequest.GetResponse()
$responseStream = $resp.GetResponseStream()
$soapReader = [System.IO.StreamReader]($responseStream)
$ReturnXml = [Xml] $soapReader.ReadToEnd()
$responseStream.Close()
write-host "Response Received."
$ReturnXml.OuterXml | out-file ".\test.xml"
write-host $ReturnXml.OuterXml
As mentioned in the other answers Powershell is probably the best way to go using the New-WebServiceProxy cmdlet.
http://technet.microsoft.com/library/hh849841.aspx
Example from the link above:
PS C:\> $URI = "http://www.webservicex.net/uszip.asmx?WSDL"
PS C:\>$zip = New-WebServiceProxy -Uri $URI -Namespace WebServiceProxy -Class USZip
PS C:\> $zip.getinfobyzip(20500).table
CITY : Washington
STATE : DC
ZIP : 20500
AREA_CODE : 202
TIME_ZONE : E