[webscraping] Authorization bearer opvragen

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Red devil
  • Registratie: December 1999
  • Laatst online: 17:51
Beste tweakerts

Voor mijn eigen SAAS webscrape ik m.b.v. Java bepaalde websites. Nu heeft 1 van deze websites een onderdeel voorzien van een Authorization bearer laag. Op dit moment laat ik de gebruikers de bearer token d.m.v. Chrome development tools opzoeken en pasten in mijn website. Niet echt gebruiksvriendelijk en nogal wat mensen hebben hier moeite mee.

Op dit moment gebruik ik OkHttp3 library in Java om de requests te maken. Heb al e.e.a. gevolgd via development tools van Chrome en kan het punt detecteren dat de bearer token beschikbaar is. Eerst zie ik een OPTIONS request:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
OPTIONS /.well-known/openid-configuration HTTP/1.1
Host: www.website.com
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: https://feature.website.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36
Access-Control-Request-Headers: authorization
Accept: */*
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Referer: https://feature.website.com/?sharedView=93c8be4b-03b6-4c4f-9de4-6a16fded085c
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,fr;q=0.8,nl;q=0.7,de;q=0.6,af;q=0.5,hu;q=0.4



gevolgd door een GET request:

code:
1
2
3
4
5
6
7
8
9
10
11
12
GET /.well-known/openid-configuration HTTP/1.1
Host    www.website.com
Connection  keep-alive
Accept  application/json, text/plain, */*
Origin  https://feature.website.com
Authorization   Bearer eyJhbGciOiJS
User-Agent  Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36
Sec-Fetch-Site  same-site
Sec-Fetch-Mode  cors
Referer https://feature.website.com/?sharedView=93c8be4b-03b6-4c4f-9de4-6a16fded085c
Accept-Encoding gzip, deflate, br
Accept-Language en-US,en;q=0.9,fr;q=0.8,nl;q=0.7,de;q=0.6,af;q=0.5,hu;q=0.4


Als ik dezelfde OPTIONS request naboots, krijg ik de volgende response headers:

code:
1
2
3
4
5
6
7
8
9
Cache-Control no-cache
Pragma no-cache
Expires -1
Access-Control-Allow-Origin https://feature.website.com
Access-Control-Allow-Credentials true
Access-Control-Allow-Headers authorization
Date Wed, 18 Dec 2019 14:39:10 GMT
Content-Length 0
Set-Cookie BNI_ServerId=00000000000000000000000099960c0a0000


Heb wat gevonden en het ziet er in principe goed uit, dus de Access-Control-Allow-Credentials true & Access-Control-Allow-Headers authorization headers zijn wat je zou verwachten, alleen zit ik met de GET die daarop volgt. Hoe krijg ik dat voor elkaar? Want de bearer token zit namelijk al in de request headers, hoe komt die daar? Klopt het dat er onder de motorkap een Javascript call plaats vindt? En zo ja, waarom wordt de traffic daarvan niet door Chrome gecaptured? Die bearer token lijkt namelijk vanuit het niets in de headers tevoorschijn te komen.

Any idea?

Beste antwoord (via Red devil op 21-12-2019 13:12)


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Red devil schreef op donderdag 19 december 2019 @ 09:11:
[...]


Yes, die response headers van die call kun je immers ook perfect bekijken met Chrome tools. Daar zit ik al steeds in te kijken. En daar staat dus niks in.
Je beseft dat je waarschijnlijk al lang ingelogd bent en die token in een cookie zit ofzo? Log eens in in een in-private sessie (a.k.a. 'porno mode'). Dan begin je in ieder geval zeker met een schone lei.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij

Alle reacties


Acties:
  • +2 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Waarom stuur je OPTIONS? Dat is iets wat de browser doet, omdat de browser iets uitvoert wat jij, als gebruiker, niet controlleert.

Dus als websiteA data wil ophalen op websiteB dan stuurt de browser een OPTIONS naar websiteB met de vraag: mag ik van websiteA iets opvragen?

Als websiteB dan antwoord 'ja', dan wordt de echte request opgestuurd.

Maar bij jouw eigen implementatie kan je rechtstreeks een POST sturen om je aan te melden, en dan op de response headers de JWT eraf halen, en toevoegen aan subsequente GET requests.

PS: heeft de website geen API?
PPS: mag je scrapen? Je stelt je als bedrijf aansprakelijk als je klakkeloos dingen overneemt.

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • Red devil
  • Registratie: December 1999
  • Laatst online: 17:51
Snake schreef op woensdag 18 december 2019 @ 22:03:
Waarom stuur je OPTIONS? Dat is iets wat de browser doet, omdat de browser iets uitvoert wat jij, als gebruiker, niet controlleert.

Dus als websiteA data wil ophalen op websiteB dan stuurt de browser een OPTIONS naar websiteB met de vraag: mag ik van websiteA iets opvragen?

Als websiteB dan antwoord 'ja', dan wordt de echte request opgestuurd.

Maar bij jouw eigen implementatie kan je rechtstreeks een POST sturen om je aan te melden, en dan op de response headers de JWT eraf halen, en toevoegen aan subsequente GET requests.

PS: heeft de website geen API?
PPS: mag je scrapen? Je stelt je als bedrijf aansprakelijk als je klakkeloos dingen overneemt.
Ik moet toegeven dat ik niet heel veel kaas gegeten heb van scraping, dus ik probeer gewoon te repliceren wat er met Chrome development tools wordt uitgevoerd. Tot nu toe gaat dat prima, ook met andere websites. Alleen loop ik nu even vast.

Bedrijf maakt onder de motorkap gebruik van APIs, die roep ik dan ook aan maar dat zijn geen officiele APIs. Zijn meer endpoints die je als eindgebruiker ook indirect gebruikt (returneren jsons die worden op je scherm worden gevisualiseerd).
M.b.t. het scrapen, het wordt gedoogd. Het is trouwens niet klakkeloos overnemen, ik voer een volledig nieuwe analyse uit op de data. Concurrent van deze website draait zelfs al mijn tool in-house, heeft licentie genomen!

Maar het probleem is dus dat die Bearer token ineens in een GET request opdoemt. Ik ben nu aan het experimenteren met headless browsers (mbv HTMLUNIT) omdat die ook Javascript zouden uitvoeren. Maar tot nu toe geen succes..

Acties:
  • +1 Henk 'm!

  • RedFox
  • Registratie: November 2001
  • Laatst online: 23:24

RedFox

Heb je een OV ofzo?

In de meeste gevallen krijg je de token terug bij het inloggen. Moet je voor deze website ook ingelogd zijn? Dan zal je die requests eerst moeten uitvoeren in je applicatie.

You are not special. You are not a beautiful or unique snowflake. You're the same decaying organic matter as everything else.


Acties:
  • +1 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Red devil schreef op woensdag 18 december 2019 @ 22:08:
[...]


Ik moet toegeven dat ik niet heel veel kaas gegeten heb van scraping, dus ik probeer gewoon te repliceren wat er met Chrome development tools wordt uitgevoerd. Tot nu toe gaat dat prima, ook met andere websites. Alleen loop ik nu even vast.

Bedrijf maakt onder de motorkap gebruik van APIs, die roep ik dan ook aan maar dat zijn geen officiele APIs. Zijn meer endpoints die je als eindgebruiker ook indirect gebruikt (returneren jsons die worden op je scherm worden gevisualiseerd).
M.b.t. het scrapen, het wordt gedoogd. Het is trouwens niet klakkeloos overnemen, ik voer een volledig nieuwe analyse uit op de data. Concurrent van deze website draait zelfs al mijn tool in-house, heeft licentie genomen!

Maar het probleem is dus dat die Bearer token ineens in een GET request opdoemt. Ik ben nu aan het experimenteren met headless browsers (mbv HTMLUNIT) omdat die ook Javascript zouden uitvoeren. Maar tot nu toe geen succes..
Dus voor uw probleem, ivm de browser, en ik negeer OPTIONS:

1. Login met username en password.
2. Server replied met een JWT token op de header van de response.
3. Javascript in de browser cached die JWT token
4. Voor iedere request wordt die JWT token op de request gezet door een stukje Javascript (geschreven door de website-developer).

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • +1 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Red devil schreef op woensdag 18 december 2019 @ 20:50:
Want de bearer token zit namelijk al in de request headers, hoe komt die daar? Klopt het dat er onder de motorkap een Javascript call plaats vindt? En zo ja, waarom wordt de traffic daarvan niet door Chrome gecaptured? Die bearer token lijkt namelijk vanuit het niets in de headers tevoorschijn te komen.

Any idea?
Ik zou eens beter kijken welke calls je zoal ziet, in principe verschijnen javascript calls ook. "Preserve log" kan hier belangrijk zijn, en beginnen met een anonieme sessie. De bearer token zal ergens vandaan komen. Eventueel HAR file opslaan en apart analyseren, alles staat daarin als het is opgenomen.
Red devil schreef op woensdag 18 december 2019 @ 22:08:
Concurrent van deze website draait zelfs al mijn tool in-house, heeft licentie genomen!
Wikipedia: Databankenrecht

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • +1 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Als een Bearer token gebruikt wordt, heeft de site mogelijk OAuth 2 authenticatie, dat al gechecked? Want dat zou impliceren dat de site die je scraped, daar mogelijk een API voor heeft en kun je mogelijk die en andere API-mogelijkheden gebruiken, waardoor je niet hoeft te scrapen.

[ Voor 4% gewijzigd door CH4OS op 19-12-2019 09:01 ]


  • Red devil
  • Registratie: December 1999
  • Laatst online: 17:51
RedFox schreef op woensdag 18 december 2019 @ 22:54:
In de meeste gevallen krijg je de token terug bij het inloggen. Moet je voor deze website ook ingelogd zijn? Dan zal je die requests eerst moeten uitvoeren in je applicatie.
Yes, ik moet ingelogd zijn en dat gaat goed. Ik kan na het inloggen bepaalde type data wel makkelijk scrapen.
Snake schreef op donderdag 19 december 2019 @ 00:36:
[...]

Dus voor uw probleem, ivm de browser, en ik negeer OPTIONS:

1. Login met username en password.
2. Server replied met een JWT token op de header van de response.
3. Javascript in de browser cached die JWT token
4. Voor iedere request wordt die JWT token op de request gezet door een stukje Javascript (geschreven door de website-developer).
1) klopt maar vanaf 2), ik zie geen enkele reply in mijn dev tools die terug gegeven wordt. De eerste keer dat de bearer authorization wordt gebruikt is in een GET request die vanaf mijn machine komt...
pedorus schreef op donderdag 19 december 2019 @ 00:54:
[...]

Ik zou eens beter kijken welke calls je zoal ziet, in principe verschijnen javascript calls ook. "Preserve log" kan hier belangrijk zijn, en beginnen met een anonieme sessie. De bearer token zal ergens vandaan komen. Eventueel HAR file opslaan en apart analyseren, alles staat daarin als het is opgenomen.

[...]

Wikipedia: Databankenrecht
Thanks voor de tips! Ik ga daar eens naar kijken. Geen idee over databankenrecht, maar de betreffende partijen staan sowieso in Amerika. Nogmaals, door de meerwaarde van de analyses wordt e.e.a. (op dit moment!) gedoogd.
CH4OS schreef op donderdag 19 december 2019 @ 01:03:
Als een Bearer token gebruikt wordt, heeft de site mogelijk OAuth 2 authenticatie, dat al gechecked? Want dat zou simpliceren dat de site die je scraped, daar mogelijk een API voor heeft en kun je mogelijk die en andere API-mogelijkheden gebruiken, waardoor je niet hoeft te scrapen.
Mmm ik zie wel e.e.a requests naar

code:
1
.well-known/openid-configuration


gaan, dat lijkt ook een soort OAuth systeem, zou dat het echt makkelijker maken?

Acties:
  • +1 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

@Red devil Heb je überhaupt contact met hen opgenomen om te vragen naar de (on)mogelijkheden?

Acties:
  • +1 Henk 'm!

  • RedFox
  • Registratie: November 2001
  • Laatst online: 23:24

RedFox

Heb je een OV ofzo?

Red devil schreef op donderdag 19 december 2019 @ 08:59:
[...]


1) klopt maar vanaf 2), ik zie geen enkele reply in mijn dev tools die terug gegeven wordt. De eerste keer dat de bearer authorization wordt gebruikt is in een GET request die vanaf mijn machine komt...
Je snapt dat het geen losse reply is, maar meestal in de response of headers van call 1 zit?

You are not special. You are not a beautiful or unique snowflake. You're the same decaying organic matter as everything else.


  • Red devil
  • Registratie: December 1999
  • Laatst online: 17:51
CH4OS schreef op donderdag 19 december 2019 @ 09:04:
@Red devil Heb je überhaupt contact met hen opgenomen om te vragen naar de (on) mogelijkheden?
Oh ja hoor, ken wel aantal mensen die daar werken. Diegene vertelde mij dat desbetreffende component niet was ontwikkeld met in het achterhoofd het laten scrapen van die website :-)
Misschien gaat die token nog wel eens weg, of misschien gaat de hele website wel achter die token.

  • Red devil
  • Registratie: December 1999
  • Laatst online: 17:51
RedFox schreef op donderdag 19 december 2019 @ 09:10:
[...]

Je snapt dat het geen losse reply is, maar meestal in de response of headers van call 1 zit?
Yes, die response headers van die call kun je immers ook perfect bekijken met Chrome tools. Daar zit ik al steeds in te kijken. En daar staat dus niks in.

Acties:
  • Beste antwoord
  • +1 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Red devil schreef op donderdag 19 december 2019 @ 09:11:
[...]


Yes, die response headers van die call kun je immers ook perfect bekijken met Chrome tools. Daar zit ik al steeds in te kijken. En daar staat dus niks in.
Je beseft dat je waarschijnlijk al lang ingelogd bent en die token in een cookie zit ofzo? Log eens in in een in-private sessie (a.k.a. 'porno mode'). Dan begin je in ieder geval zeker met een schone lei.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • +1 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-07 13:42
Waarom pak je die bearer token en log je niet gewoon zelf in vanuit de scraper? Dan hoef je maar 1 keer de logingegevens vast te leggen. Die bearer token krijg de client (browser, je scraper) na login.

https://niels.nu


  • Red devil
  • Registratie: December 1999
  • Laatst online: 17:51
RobIII schreef op donderdag 19 december 2019 @ 10:16:
[...]

Je beseft dat je waarschijnlijk al lang ingelogd bent en die token in een cookie zit ofzo? Log eens in in een in-private sessie (a.k.a. 'porno mode'). Dan begin je in ieder geval zeker met een schone lei.
thanks, ga ik proberen! Ik heb wel gezien dat de bearer vaak veranderd maar jij denkt dat hij ergens in een cookie verborgen zou kunnen zitten?
Hydra schreef op donderdag 19 december 2019 @ 10:33:
Waarom pak je die bearer token en log je niet gewoon zelf in vanuit de scraper? Dan hoef je maar 1 keer de logingegevens vast te leggen. Die bearer token krijg de client (browser, je scraper) na login.
Met de scraper log ik al in, alleen dan geen teken van bearer. Op dit moment geef ik de bearer als extra toe en dan werkt alles, alleen kan ik de bearer dus niet zien na het inloggen met de scraper.

Acties:
  • +1 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-07 13:42
Red devil schreef op donderdag 19 december 2019 @ 10:48:

Met de scraper log ik al in, alleen dan geen teken van bearer.
Die token staat ergens in een login response. Maar daar staat dan natuurlijk niet de tekst "bearer" in. Je moet kijken naar dat stukje wat achter "bearer" staat; dat zal ergens in de response zitten.

https://niels.nu


Acties:
  • +1 Henk 'm!

  • elhopo
  • Registratie: December 2005
  • Laatst online: 22-07 14:16
Normaal staat je bearer in de response headers of in je cookie wat je terug krijgt.

De inhoud van de bearer hierboven is niet compleet, maar ik neem aan dat je dat bewust hebt gedaan? De inhoud van de bearer is
{"alg":"R
Lijkt me in dit geval dat het in een cookie staat, en dat kan je, mits de headers niet op HTTPonly staan, er in Javascript gewoon weer uitpeuteren en meesturen. Je zou dat kunnen vinden door in de response headers te kijken of er ergens een set-cookie in staat.

Wat je ook nog kan proberen is de username en het password in de headers mee te sturen. Afhankelijk van hun implementatie kan dat ook wel werken.

Overigens is het idee om je code op de bearer te baseren niet echt slim. Veel websites veranderen die per request, omdat dat veiliger is. Mocht de website die je aan het scrapen bent dit ooit aanpassen dan werkt je code niet meer.

Blijkt dat citroenvlinders helemaal niet naar citroen smaken.


Acties:
  • +1 Henk 'm!

  • Xalephsis
  • Registratie: Augustus 2009
  • Laatst online: 28-05 15:40
Je kunt die token ook gewoon opvragen d.m.v. oAuth2, je moet het inlog proces repliceren, de JSON response afvangen en als je alles op de juiste manier uitvoert, heb je uiteindelijk je Bearer token.

Ik zou eens kijken naar hoe oAuth2 werkt en dan specifiek OpenID wat een authenticatie laag is die door middel van oAuth2 werkt. Als ik die headers zie kwam ik OpenId tegen, dus ik zou daar beginnen.

Het principe is vrij eenvoudig, je doet een request op /oauth/authorize, als die constateert dat je geen (valide) Bearer token hebt, redirect deze je naar /oauth/token waar je een token kunt opvragen ( of inloggen gaat, afhankelijk van het type grant dat je mee stuurt ( en zij accepteren) )

Na het inloggen kun je direct een Bearer token krijgen als ze het slecht geïmplementeerd hebben, of, als ze het wat veiliger doen, een authorization_code, in dat laatste geval moet je nog een request doen om je authorization_code om te zetten naar een Bearer token. Ik ga er alleen niet vanuit dat dit hier het geval is, want die app waar je vanaf scraped hebben ze waarschijnlijk zelf in beheer.

Acties:
  • +1 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-07 13:42
elhopo schreef op donderdag 19 december 2019 @ 13:57:
Normaal staat je bearer in de response headers of in je cookie wat je terug krijgt.
Of in de response body, of in een redirect URL... Dit is geen 'standaard'; dat zal 'ie zelf uit moeten vogelen door gewoon de login flow kwa requests te volgen. Maar omdat de TS nooit zelf die login doet, komt 'ie daar niet achter. Kip-ei verhaal voor hem dus.

Die OPTIONS call is geen login; het is gewoon een check.

https://niels.nu


Acties:
  • 0 Henk 'm!

  • Red devil
  • Registratie: December 1999
  • Laatst online: 17:51
Hydra schreef op donderdag 19 december 2019 @ 18:25:
[...]


Of in de response body, of in een redirect URL... Dit is geen 'standaard'; dat zal 'ie zelf uit moeten vogelen door gewoon de login flow kwa requests te volgen. Maar omdat de TS nooit zelf die login doet, komt 'ie daar niet achter. Kip-ei verhaal voor hem dus.

Die OPTIONS call is geen login; het is gewoon een check.
Ah ik denk dat ik niet helemaal duidelijk was, ik doe dus wel zelf de login. Anders zou ik immers nooit de andere data kunnen scrapen. Ik ben wel wat verder gekomen.

Door deze hint ben ik gaan testen in incognito mode:
RobIII schreef op donderdag 19 december 2019 @ 10:16:
[...]

Je beseft dat je waarschijnlijk al lang ingelogd bent en die token in een cookie zit ofzo? Log eens in in een in-private sessie (a.k.a. 'porno mode'). Dan begin je in ieder geval zeker met een schone lei.
En daar kwam ik inderdaad e.e.a. tegen. O.a. deze link:

code:
1
2
3
String state = "blaaaat%3B%2F";
String nonce = "blaaaat";
https://www.website.com/protocol/openid-connect/auth?response_type=id_token&client_id=website-2.0&state="+state+"&redirect_uri=https%3A%2F%2Ffeature.website.com%2F&scope=openid&nonce="+nonce;


Vervolgens zag ik in deze code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
cookieStore = new CookieStore();

            client = new OkHttpClient.Builder().cookieJar(cookieStore).connectTimeout(15, TimeUnit.SECONDS)
                    .writeTimeout(15, TimeUnit.SECONDS).readTimeout(15, TimeUnit.SECONDS)
                    .addNetworkInterceptor(new Interceptor() {
                        @Override
                        public Response intercept(Chain chain) throws IOException {
                            cookieStore.addChainUrl(chain.request().url());
                            if (debug) {
                                System.out.println("url: " + chain.request().url());
                            }
                            return chain.proceed(chain.request());
                        }
                    }).build();


In de url de Bearer token langs komen! Alleen zit ik nu met die state en nonce

Ik zie deze niet voorbij komen in mijn requests. Ik heb ze nu gehardcode op basis van mijn eigen Chrome sessie. Heb circa 10 verschillende logins getest en ze werken allemaal met deze nonce en state maar ja, voor hoe lang?

Acties:
  • +2 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Hydra schreef op donderdag 19 december 2019 @ 18:25:
[...]


Of in de response body, of in een redirect URL... Dit is geen 'standaard';
In dit geval lijkt het echter wel een standaard te zijn getuige de URL van de OpenID configuration URL in de start post.

https://openid.net/connect/ hier is er meer informatie te vinden.
Red devil schreef op vrijdag 20 december 2019 @ 11:52:
[...]

Alleen zit ik nu met die state en nonce

Ik zie deze niet voorbij komen in mijn requests. Ik heb ze nu gehardcode op basis van mijn eigen Chrome sessie. Heb circa 10 verschillende logins getest en ze werken allemaal met deze nonce en state maar ja, voor hoe lang?
De state een Nonce kun je ook in de documentatie terug vinden. Heel kort door de bocht moet je dat gewoon per login sessie een random waarde meegeven die niet bij anderen bekent is. Het voegt een laag security toe.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1