jsoup einloggen klappt nicht

Fohnbit

Top Contributor
Hallo!

Ich möchte mich an einer Webseite via jsoup einloggen, aber erhalte immer Error 400.
Wenn ich das einloggen in Chrom anschaue, erhalte ich:
Code:
Request URL: https://company.com/account/login/sTarget/account/sTargetAction/index
Request Method: POST
Status Code: 302
Remote Address: 71.71.214.35:443
Referrer Policy: strict-origin-when-cross-origin
cache-control: no-cache, private
content-length: 0
content-type: text/html; charset=UTF-8
date: Mon, 25 Apr 2022 06:54:12 GMT
location: https://company.com/
server: Apache
set-cookie: session-1=tbe8hd5qo2tf41mo6l79l8d7mh; expires=Mon, 02-May-2022 06:54:13 GMT; Max-Age=604800; path=/; secure; HttpOnly
set-cookie: slt=26629e16-a6b3-4e77-9fd2-c1575f90bc7a.1; expires=Tue, 25-Apr-2023 06:54:13 GMT; Max-Age=31536000; path=/; secure; httponly
set-cookie: nocache=price-1; path=/; secure; httponly
set-cookie: x-cache-context-hash=090ea158954ee6bccdc69bdaf3a53a86216e8489; path=/; secure
vary: User-Agent
x-powered-by: PHP/7.4.28
:authority: company.com
:method: POST
:path: /account/login/sTarget/account/sTargetAction/index
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
accept-encoding: gzip, deflate, br
accept-language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
cache-control: max-age=0
content-length: 122
content-type: application/x-www-form-urlencoded
cookie: __csrf_token-1=3Yq16LSlPEvnxRS3fnDFClcPYBU3zc; cookieDeclined=1; session-1=p9jv3sk2mordb5fdk57tf4rj9c
origin: https://company.com
referer: https://company.com/account
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-dest: document
sec-fetch-mode: navigate
sec-fetch-site: same-origin
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36

mit den Post Daten:
Code:
sTarget: account
email: user@company.com
password: CGyd@7c4sPqpfP
Submit:
__csrf_token: 3Yq16LSlPEvnxRS3fnDFClcPYBU3zc

In jsoup erhalte ich aber:
Java:
org.jsoup.HttpStatusException: HTTP error fetching URL. Status=400, URL=https://company.com/account/login/sTarget/account/sTargetAction/index
    at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:760)
    at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:705)
    at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:295)

        at java.base/java.lang.Thread.run(Thread.java:834)

mein Code:
Java:
try {
            res = Jsoup.connect("https://company.com/account/login/sTarget/account/sTargetAction/index")
                    .data("Submit", "").data("sTarget", "account").data("email", "user@company.com")
                    .data("password", "CGyd@7c4sPqpfP").method(Method.POST).execute();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
 
Wenn Du den Code 400 bekommst, dann schickt dein Client einen Request, der nicht verarbeitet werden kann. Da wir aber keine Informationen haben, wie Du mit den Request genau gebaut hast, können wir da vermutlich nicht mehr zu sagen.
 
Hallo Konrad!

Danke ... den Java Code habe ich angehängt. Das wäre nur ein Einzeiler.

Den Ablauf der Webseite habe ich mit Chrom versucht raus zu kopieren.

Was würdest du noch genau benötigen?

An sich muss ich die URL für die Übergabe der Post Parameter finden und die Post Parameter ebenso.

Dachte ich habe das alles im Aufruf der URL drinnen.
 
Ok, hatte ich das eben übersehen oder wurde es noch editiert? Ist aber erst einmal egal.

Und @LimDul war schneller ... ich habe einen anderen Link, der es zeigen würde:

Neben dem csrf Token fehlt evtl. auch der x-www-form-urlencoded header.
 
Danke!

Soweit ich gesehen habe, wird der csrf Token über:
geholt.

Öffne ich die Seite, erhalte ich im response header:
Code:
cache-control: no-cache, private
content-type: text/html; charset=UTF-8
date: Mon, 25 Apr 2022 07:55:16 GMT
server: Apache
set-cookie: x-cache-context-hash=deleted; expires=Sun, 25-Apr-2021 07:55:16 GMT; Max-Age=0; path=/
set-cookie: nocache=deleted; expires=Sun, 25-Apr-2021 07:55:16 GMT; Max-Age=0; path=/; secure; httponly
vary: Accept-Encoding,User-Agent
x-content-encoding-over-network: br
x-csrf-token: qYcKhUQrC3wsW8zsoHmUSsv7PL8Be5
x-powered-by: PHP/7.4.28

Mein neuer Code ist dann so:
Java:
    Response res = null;
        try {

            Connection.Response res1 = Jsoup.connect("https://company.com/csrftoken").method(Method.GET).execute();
            Map<String, String> welcomCookies = res1.cookies();

            String securityTokenKey = "__csrf_token";
            String securityTokenValue = res1.header("x-csrf-token");

            res = Jsoup.connect("https://company.com/account/login/sTarget/account/sTargetAction/index")
                    .header("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8").data("Submit", "").data("sTarget", "account").data("email", "user@company.com")
                 .data("password", "CGyd@7c4sPqpfP").
                    .data(securityTokenKey, securityTokenValue).cookies(welcomCookies).method(Method.POST).execute();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

Aber nach wie vor Error 400
 
Was die Sache generell schwierig macht, ist zweierlei:
a) ein 400er Fehler ist erstmal ohne Zugriff auf die Server Logs schwer zu debuggen in dem Sinne, dass du nicht weiß, was exakt fehlt
b) Grundsätzlich sind viele Webanwendungen heutzutage so gebaut, dass man nicht einfach über GET/POST Aufrufe simulieren kann, sondern es möglichst korrekt machen muss. Als Schutz vor Cross Site Scripting, aber auch vor Bots & Co.

Sprich das was du tust, ist etwas was in der Regel aktiv verhindert werden soll.

Dir wird nichts anderes übrig bleiben als die gesamte Netzwerkkommunikation (Auch Javascript Requests etc.) zu monitoren im Browser und dann zu bewerten, was relevant ist. Insbesondere auch zu debuggen - bei deinem neuen Code, hast du denn wirklich ein csrf Token dann bekommen? Hast du da mal rein debugged.

Hinzu kommt, dass der originale Request ja noch mehr Tokens hatte, unter anderem auch eine Session. Die wird vermutlich auch wichtig sein.
 
Ja, ich weiß das es für Euch schwer ist, ohne direkt Zugriff.

Aber mit Chrome und dem Network Chart sehe ich an sich alles?
session-1 und slt werden bei der csfr Abfrage mit übergeben ... da muss ich noch suchen
 
Schau Dir wirklich die Requests im Detail an. Dazu dann zur Not auch einen Proxy nutzen, der alles genau anzeigt. Dann kannst Du die Requests 1:1 vergleichen um zu sehen: Was für Unterschiede gibt es? Dann kannst Du deine Requests entsprechend anpassen, so dass eben alles stimmig ist.
(Und viel Spass, wenn sich da dann bei einer neuen Version etwas ändert - dann kommt das erneut auf Dich zu!)

Ansonsten scheint das crsf Token als Coockie mitgegeben zu werden:
cookie: __csrf_token-1=3Yq16LSlPEvnxRS3fnDFClcPYBU3zc; cookieDeclined=1; session-1=p9jv3sk2mordb5fdk57tf4rj9c
Daher ist das wohl nicht per .data(...) zu setzen sondern in den cookie zu packen.

Oder habe ich das jetzt missverstanden? Das ist halt keins meiner Kernthemen so dass ich da wenig praktische Erfahrungen habe.
 

Zurück
Oben