Would someone please help me to understand how I might inject into my program a query to this webpage?
There are two parameters that need to be set, i.e.
"Site:", is where you enter the language and site code.
&
"Page:", you must put in the exact title of the page as it appears on the connected site.
The URL's always look like this:
https://www.wikidata.org/wiki/Special:ItemByTitle?site=en&page=Mikhail+Bakunin&submit=Search
https://www.wikidata.org/wiki/Special:ItemByTitle?site=en&page=Thomas+Edward+Lawrence&submit=Search
and the language is always English, so you see, it's just:
https://www.wikidata.org/wiki/Special:ItemByTitle?site=en&page=Blah+Blah&submit=Search
The objective of querying that page is to retrieve the ID value associated with the page, so for Mikhail Bakunin it's Q27645 and for T. E. Lawrence it's Q170596
It becomes part of the URL once the page is reached:
https://www.wikidata.org/w/index.php?title=Q170596&site=en&page=Thomas+Edward+Lawrence&submit=Search
But also maybe I could strip it from the page, using beautifulSoup or soemthng?(that's a guess)
The program needs to be generalizable, which is to say, that the name of the entity we're searching for is variable, it will change in the program, so that needs to be taken in account.
I guess using python or php or something would not be a crime against humanity if it's easier, though I prefer java.
update:
import java.net.*;
import java.io.*;
public class URLConnectionReader
{
public static void main(String[] args) throws Exception
{
URL site = new URL("https://www.wikidata.org/wiki/Special:ItemByTitle?site=en&page=Mikhail+Bakunin&submit=Search");
URLConnection yc = site.openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader(
yc.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}
this works sort of, but the result is quite messy.
I guess I could grab it out of this thing:
<!-- wikibase-toolbar --><span class="wikibase-toolbar-container"><span class="wikibase-toolbar-item wikibase-toolbar ">[<span class="wikibase-toolbar-item wikibase-toolbar-button wikibase-toolbar-button-edit">edit</span>]</span></span>
but how?
When you request this URL the response is:
HTTP/1.1 302 forced.302
Server: Apache
X-Powered-By: HHVM/3.3.1
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Vary: Accept-Encoding,X-Forwarded-Proto,Cookie
X-Content-Type-Options: nosniff
Location: http://www.wikidata.org/w/index.php?title=Q27645&site=en&page=Mikhail+Bakunin&submit=Search
Content-Type: text/html; charset=utf-8
X-Varnish: 1641959068, 1690824779, 1606045625
Via: 1.1 varnish, 1.1 varnish, 1.1 varnish
Transfer-Encoding: chunked
Date: Fri, 17 Apr 2015 11:49:55 GMT
Age: 0
Connection: keep-alive
X-Cache: cp1054 miss (0), cp3003 miss (0), cp3013 frontend miss (0)
Cache-Control: private, s-maxage=0, max-age=0, must-revalidate
Set-Cookie: GeoIP=NL:XXX:51.4400:5.6194:v4; Path=/; Domain=.wikidata.org
So there's a 302 redirect in the HTTP response headers. That's where you'll want to grab your Q-number. Simlpy regex it out of the Location header with a regex like:
^Location:.*?title=(Q[0-9]+)
...and use matchgroup 1 (should be Q27645).
To grab the HTTP headers, have a look at this page; it basically goes like:
URL obj = new URL("https://www.wikidata.org/wiki/Special:ItemByTitle?site=en&page=Mikhail%20Bakunin&submit=Search");
URLConnection conn = obj.openConnection();
//get header by 'key'
String location = conn.getHeaderField("Location");
//TODO: Regex here
Related
A customer will link to one of our webpages on their site: customer.site/links.html
A person clicks that link and gets sent to our.site/webapp/handlerequest.aspx?someparam=somevalue
The value of someparam is set in a cookie with SameSite=Strict and then uses a 302 redirect to another page on the same domain:
Request URL: https://our.site/webapp/handlerequest.aspx?someparam=somevalue
Request Method: GET
Status Code: 302
Remote Address: ...
Referrer Policy: strict-origin-when-cross-origin
cache-control: private
content-length: ...
content-type: text/html; charset=utf-8
date: ...
location: /webapp/someotheraction
server: Microsoft-IIS/10.0
set-cookie: someparam=somevalue; expires=Thu, 17-Mar-2022 14:41:13 GMT; path=/; secure; HttpOnly; SameSite=Strict
strict-transport-security: max-age=31536000
x-frame-options: SAMEORIGIN
The browser does NOT include this cookie on the 302 redirect to /webapp/someotheraction.
This only starting happening when we specifically change our code to set this cookie to SameSite=Strict.
This occurs in Chrome, Firefox, Edge, and IE (old IE)
Is this on purpose? Why? Since we are going from one request on the domain to another request in the same domain, shouldn't the SameSite=Strict cookies be included? Does this have anything to do with the referer policy defaulting to strict-origin-when-cross-origin? https://www.w3.org/TR/referrer-policy/ doesn't say anything about cookies
This is a cross-site request because the initial navigation was cross-site (from customer.site to our.site). Strict cookies are never sent on cross-site requests. It doesn't matter that the request gets redirected (in this case, to another URL on our.site), just the fact that the user clicked on a cross-site link means the request is cross-site.
As for why this is the case, it's because the origin responsible for initiating the navigation is important in preventing cross-site request forgery (CSRF). Imagine if https://evil.site had a link to https://bank.site/transfer-funds which redirects to https://bank.site/transact. We wouldn't want Strict cookies to be send to the /transact endpoint after the redirect, even if it was redirected to by the same site, because the initiating origin is cross-site.
I want to extract values from Response Headers and store them as Strings and eventually make assertions with certain values.
From the following Response Header I want to extract * Set-Cookie:id=xxxxxx-xxxxxxx-xxxxxx; and store it.
I am using Rest Assured. Thanks!
Response Headers
* Cache-Control:no-cache, no-store, must-revalidate
* Connection:keep-alive
* Content-Length:108
* Content-Type:image/png
* Date:Wed, 22 Mar 2017 13:19:51 GMT
* Expires:0
* Pragma:no-cache
* Server:nginx/1.4.6 (Ubuntu)
* Set-Cookie: AWSELB=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX;PATH=/;DOMAIN=.xxxx.xxxxx.com;MAX-AGE=3600;VERSION=1
* Set-Cookie:id=xxxxxx-xxxxxxx-xxxxxx; Version=1; Path=/; Domain=.xxxx.xxxxx.com; Max-Age=157680000
* Set-Cookie:Session=xxxx-xxxxxx-xxxxxx-xxxxx; Version=1; Path=/; Domain=.xxxxx.xxxxxx.com; Max-Age=3600
* X-Powered-By:Xxxxxxxx/1
* X-Robots-Tag:noindex, nofollow
Slightly adapted from the doc : https://github.com/rest-assured/rest-assured/wiki/Usage#headers-cookies-status-etc
Cookies
To get all values for a cookie you need to first get the Cookies object from the Response object. From the Cookies instance you can get all values using the Cookies.getValues() method which returns a List with all cookie values.
Simple values as String :
import io.restassured.http.Cookie;
import io.restassured.http.Cookies;
import io.restassured.response.Response;
Map<String, String> allCookies = get("https://www.stackoverflow.com").getCookies();
List<String> myCookieValues = allCookies.getValues("myCookieName");
To get all fields from cookies, you need detailed cookies :
Cookies allDetailedCookies = get("https://www.stackoverflow.com").getDetailedCookies();
Cookie myCookie = allDetailedCookies.get("myCookieName");
myCookie.getValue();
myCookie.getDomain();
myCookie.getExpiryDate();
myCookie.getMaxAge();
...
If multi valued cookie :
List<Cookie> myCookies = allDetailedCookies.getList("myCookieNAme");
You can assert on cookie with hamcrest matchers :
import static io.restassured.RestAssured.when;
import static org.hamcrest.Matchers.hasValue;
when()
.get("https://www.stackoverflow.com").
then()
.cookie("myCookieName", hasValue("value"));
Doc recommends imports from :
io.restassured.RestAssured.*
io.restassured.matcher.RestAssuredMatchers.*
org.hamcrest.Matchers.*
I work on a app using angular.dart at the clientside and dart in the serverside.
I have write a login rest entrypoint and want to set cookies the header was in the response but the cookies are not set.
set-cookie:app-user=533c1470a2658184a7625d7d; Expires=Tue, 8 Apr 2014 9:15:47 GMT; Domain=.ballr.eu; Path=/
set-cookie:app-tokn=530fa71b615e168787a7cb5b5c589a5601065e1e3f921d4b770c784394de3a42; Expires=Tue, 8 Apr 2014 9:15:47 GMT; Domain=.ballr.eu; Path=/
I try to check my headers or my value set in cookies, but to my mind is good
headers :
request.response..statusCode=HttpStatus.OK
..headers.set(HttpHeaders.CONTENT_TYPE, 'text/plain: charset=UTF-8')
..headers.add("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, DELETE")
..headers.add("Access-Control-Allow-Headers", "origin, x-requested-with, content-type, accept")
..headers.add("Access-Control-Allow-Origin", "*");
cookies :
static setCookie(HttpRequest request, String key, String value, DateTime duration) =>
request.response.cookies.add(new Cookie(key, value)..path = '/'
..expires = duration
..domain = '.app.eu');
I follow some threads on stackoverflow and google groups and I think it's a problem of "withCredientals" a value I have set in an another projet (angular/Java) but I don't find this parameter on angular.dart.
Can you help me to find it or have you somes ideas?
Thank you for your help/time
I'm not sure if I understand you question correctly but maybe this is what you are looking for:
(on the client)
var request = new HttpRequest()
..open("POST", uri.toString(), async: true)
..withCredentials = true // seems to be necessary so that cookies are sent
EDIT
I missed that this is about Angular. This needs a slightly different approach.
If you use the Angular http service you have a parameter
class MyController {
Http _http;
MyController(this._http) {
_http.getString('someurl', withCredentials: true).then((e) => ...);
// or _http.request('someurl', method: 'POST', withCredentials: true).then((e) => ...);
}
}
I am working on a REST-based app that connects to Office365. The app will be available on multiple platforms, so I have created a portable class library to handle all the logic, including authentication. The PCL targets Windows Phone 7.1 and onwards, and includes the Microsoft HTTP Client Libraries (NuGet), which is required for Windows Phone 7.1 apps.
The last step of the authentication for Office365 is to get a FedAuth cookie from the site, and that is where I am having a problem.
The code I use to get the cookie is:
var handler = new HttpClientHandler();
handler.AllowAutoRedirect = false;
var newClient = new HttpClient(handler);
var newResponse = await newClient.PostAsync(host + "/_forms/default.aspx?wa=wsignin1.0", new StringContent(binarySecurityToken));
The 'host' variable is just the URL of the Office365 site, and the binarySecurityToken I got from previous requests. These things work equally well in all the apps: Whether I run the PCL code from the context of a Windows Phone 7.1 app, Windows Phone 8 app, Windows 8 app, or even a Console application, I am getting exactly the same response (see below), which contains the FedAuth cookie. This I have verified using Fiddler.
Then I try to get the cookie to reuse it on subsequent requests.
var cookieCollection = handler.CookieContainer.GetCookies(new Uri(host));
foreach (var cookie in cookieCollection)
{
if (cookie.Name.StartsWith("FedAuth"))
{
//TODO: Store the cookie.
return true;
}
}
This leads to the following result: On Windows Phone 7.1 the 'cookieCollection' variable only contains the cookie rtFa'. On the other platforms it contains all three cookies 'RpsContextCookie', 'rtFa', 'FedAuth'.
Windows Phone 7.1 differs from the other apps in that this is the only platform that actually uses the HttpClient from the NuGet package. The other platforms have a native HttpClient that is swapped in by the magic of PCL.
It seems likely that the problem is caused by the FedAuth cookie not having a domain. I have tried using .GetCookies(null), and different variations of .GetCookies(new Uri("something", UriKind.Relative)), which all result in an exception. I have also tried changing most of the properties of the HttpClientHandler without luck.
Has anyone encountered this problem, and perhaps solved it? Or just a suggestion on what I could try?
The response I get on the .PostAsync above is the same on all platforms, and according to Fiddler the raw response is:
HTTP/1.1 302 Found
Cache-Control: no-cache, no-store
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Expires: -1
Location: /
Server: Microsoft-IIS/7.5
X-SharePointHealthScore: 0
X-AspNet-Version: 4.0.30319
Set-Cookie: RpsContextCookie=; path=/
Set-Cookie: rtFa=+13jGMMp0A0V+driESaO30ixYclFCRjEvS2jMSwXPfQcrefiJvLEExxYu7V+1JZHM6X5JWeuL70jb3/N/Q/hUTwoAiC/XLJZ1QfERi4aUt8AAVF4ekcNyMdWnj65foDwPkhaV5z8whNSZQigBFD/2Vc1xMTH0ukHbS4cbtJO5U28/4g66vgIZg7dGpNOZg2jDt+HF3GSQ4/W+T1oS9/F5e+Pbwd0p8mqPhkGjL+M7IptmkeHoIqVcS4Ps25dM6q1AniLiv/3NujYmrQjseaEYZ2aaCfc7ZHX7LygBZm8KsoGNyTYRPmC+hZ7tsDq6wfto+xVpX1scggsU0+Qty3DPWUiwy1bBy8JR0znFG0+eDt9uBOQzqfOSjVvd8WNIKUFIAAAAA==; domain=sharepoint.com; path=/; HttpOnly
Set-Cookie: FedAuth=77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48U1A+RmFsc2UsMGguZnxtZW1iZXJzaGlwfDEwMDMwMDAwODc5MTUwMGVAbGl2ZS5jb20sMCMuZnxtZW1iZXJzaGlwfHRtakB3aWxkY293Lm9ubWljcm9zb2Z0LmNvbSwxMzAzNDIwOTYxNDAxMTIxMzMsRmFsc2UsV2lSQjlUVTdOSTk0MUpKRWZ5d1JDNTFPYUphMVpWNkJqWWdaVGM3MU00U3lqL2VkTnF6dVJpbXdEMnpEWk9oR1lybkFsNnpWb3M4V0FBZDk1VVYrZkt5dlkwQ3dqRTlyaEhEc256bkZUeENoODU1Rm1JZmxoYVBkMTFQS2VjWnFJN0N4OUxUOHk4enZDaVNUTGNQMzR2K3NOeHk1YXBMZ2NIWDNHR3JMcG1Ic24rQzAzUkUzakNDQWhma2F3RVRQbk03R3JycVk5amJseHJmNVNhNHZxMk91NlN1cGszZnpQMUZQTzJBc1UrRXZvSDgvWTllR2Y3c2x2dStvMnVlN3hZLy9VQ1lYU1U4b3AzckZ6c2laK0wwN1NrUnZYMTZjVklUVVZJZ0x6TGIxaTJLd2lwNGp6RHgwRFdmVWF0Rk42UVFaNWhHRzMyOHRJZjI2RXo4YldnPT0saHR0cHM6Ly93aWxkY293LnNoYXJlcG9pbnQuY29tLzwvU1A+; path=/; secure; HttpOnly
SPRequestGuid: 5bb2689c-d7c5-c07c-4890-ee32437f15f5
request-id: 5bb2689c-d7c5-c07c-4890-ee32437f15f5
SPRequestDuration: 125
SPIisLatency: 2
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 16.0.0.2308
X-Content-Type-Options: nosniff
X-MS-InvokeApp: 1; RequireReadOnly
P3P: CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI"
Date: Thu, 09 Jan 2014 21:46:53 GMT
Content-Length: 118
<html><head><title>Object moved</title></head><body>
<h2>Object moved to here.</h2>
</body></html>
I found an answer of kind here: Accessing HTTPOnly cookies from Windows Phone 8/PCL.
Reading the post I realized that I made an error above: I was not getting the 'rtFa' cookie in the Windows Phone 7.1 app, but the 'RpsContextCookie'. The cookies I couldn't access were both marked with HttpOnly.
I also realized that I don't need to access the cookies directly. Instead, I could just reuse the handler.CookieContainer. So my code now looks like this:
var handler = new HttpClientHandler();
handler.AllowAutoRedirect = false;
var newClient = new HttpClient(handler);
var newResponse = await newClient.PostAsync(host + "/_forms/default.aspx?wa=wsignin1.0", new StringContent(binarySecurityToken));
this._cookieContainer = handler.CookieContainer;
return true;
this._cookieContainer is just a class-scoped field for storage of the cookie container. Then, once I am authenticated and I do the requests that are the actual purpose of the app, I do the following:
var handler = new HttpClientHandler(){ CookieContainer = this._cookieContainer };
var client = new HttpClient(handler);
var response = await client.GetAsync(host + "something");
So the bottom line is: I can't access the HttpOnly cookies - but I don't need to. I just reuse the cookie container, and the cookies are automatically included in the next request.
This works both in Windows Phone 7.1 apps, Windows Phone 8 apps, Console applications etc.
I'm trying to connect to a https web service (not .NET as far as I know).
I can't control the other side in any way, I just got some standards and a wsdl to operate
with it.
I have created at first the client using Add Service Reference, tried some things until I get through some problems, where one most serious was that I couldn't add the Authentication header to the message which was resulting in fail.
Added the service using old Add Web Reference and seemed more easily managed and appropriate, using a partial class and override the GetWebRequest, I added this code so I can preauthenticate with the service and add the security header, which they don't mention in the wsdl link. I know that it is not mandatory for services to tell this but it would be nice my Web Service creators fellow developers.
protected override WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(uri);
if (PreAuthenticate)
{
NetworkCredential networkCredentials = Credentials.GetCredential(uri, "Basic");
if (networkCredentials != null)
{
byte[] credentialBuffer = new UTF8Encoding()
.GetBytes(networkCredentials.UserName + ":" + networkCredentials.Password);
request.Headers["Authorization"] = "Basic" + Convert.ToBase64String(credentialBuffer);
}
else
{
throw new ApplicationException("No network credentials");
}
}
return request;
}
To call the service I added this code:
using (Service client = new Service()) // autogenerated Service class
{
client.EnableDecompression = true;
// Create the network credentials and assign
// them to the service credentials
NetworkCredential netCredential = new NetworkCredential("test1", "test1");
Uri uri = new Uri(client.Url);
ICredentials credentials = netCredential.GetCredential(uri, "Basic");
client.Credentials = credentials;
// Be sure to set PreAuthenticate to true or else
// authentication will not be sent.
client.PreAuthenticate = true;
// Make the web service call.
Request req = new Request { UserName = "test2", Password = "test2"; // an object created from autogenerated code
RequestResult result = client.processMessage(req); // autogenerated code
}
While testing this call and checking with fiddler my request. I see 2 calls a keep alive call with these header, nothing special.
CONNECT server:443 HTTP/1.1
Host: server
Connection: Keep-Alive
Sending 570 returning a 200 result.
HTTP/1.1 200 Connection Established
FiddlerGateway: Direct
StartTime: 00:05:13.743
Connection: close
And the call with the data sending 571 result 500 error:
POST /host/Service HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.5448)
Authorization: BasicdXNlcOTc3MzQyMGTDFTR4dftfrdg5 // changed this hash for security reasons
VsDebuggerCausalityData: // Removed this hash for security reasons
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Host: server-host-url
Content-Length: 7238
Expect: 100-continue
Accept-Encoding: gzip
Connection: Keep-Alive
The error exception in .NET client:
Error on verifying message against security policy Error code:1000
As you see the Authorization header exist. I also tried with adding a space after Basic you can see above where exactly in the overriden method, and seemed fiddler recognized it better and also decoded the username:password header.
This results into that response:
HTTP/1.1 500 Internal Server Error
Date: Sat, 21 Apr 2012 21:05:22 GMT
Server: Oracle-Application-Server-11g
X-Powered-By: Servlet/2.5 JSP/2.1
X-Cnection: close
Transfer-Encoding: chunked
Content-Type: text/xml;charset="utf-8"
Content-Language: en
X-Pad: avoid browser bug
Set-Cookie: BIGipServerpoolXoas243_254_9999=437682499.99988.0000; path=/
The strange thing I wonder first is if the first call should be preauthenticated, the handshake keep alive one? This 500 error I know that causes when authentication header is not present, but mine is. Preauthentication is what I need to know how it should happen and I guess it's not working if it should appear in the 1st message.
Another strange thing is that if I change the 2 pairs of passwords opposite, I see on fiddler that I get 3 messages, 1 with the handshake and result in 200 and "TWO" others with 401 Authorization Required.
This drives me crazy. Any help appreciated to save my soul.
Thank you!