java 如何使用 cURL 登录 Spring Security 登录表单?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13048954/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 11:19:19  来源:igfitidea点击:

How to login to a spring security login form using cURL?

javacurlspring-security

提问by Seyed Vahid Hashemi

I am working on a springMVC project in which the user authentication is based on spring security.

我正在开发一个 springMVC 项目,其中用户身份验证基于 spring 安全性。

the idea is to have a mobile (android) application to be able to send some sort of data to backend.

这个想法是有一个移动(android)应用程序能够向后端发送某种数据。

So before get my hand dirty into android developing I decided to mock the situation of login form using cURL.

因此,在接触 android 开发之前,我决定使用 cURL 模拟登录表单的情况。

the login form in our site is as following :

我们网站的登录表单如下:

http://localhost:8080/app/user/login

and I use following command :

我使用以下命令:

curl -F 'username=admin&password=admin' http://localhost:8080/app/user/login

but yet I will get login page in other words I am not able to pass user authentication based on a mock up situation.

但是我将获得登录页面,换句话说我无法根据模拟情况通过用户身份验证。

just to note : for every request the spring secure will create a randomize token something similar to :

请注意:对于每个请求,spring secure 将创建一个类似于以下内容的随机令牌:

8863F732ADDE24CD167F4EF502A4333D

8863F732ADDE24CD167F4EF502A4333D

how should I pass login form based on spring security using mock situation (either cURLor HTTPClient)

我应该如何使用模拟情况(cURLHTTPClient)传递基于 spring 安全性的登录表单

回答by Aleksandr M

Use cURLlike this:

cURL像这样使用:

 curl -d j_username=admin -d j_password=admin -L http://localhost:8080/app/j_spring_security_check

CSRF

CSRF

If you get something like Expected CSRF token not found. Has your session expired?that means that CSRF token protection is enabled. To test it with cURL you need a cookie and a CSRF token itself.

如果您得到类似的信息Expected CSRF token not found. Has your session expired?,则意味着启用了 CSRF 令牌保护。要使用 cURL 对其进行测试,您需要一个 cookie 和一个 CSRF 令牌本身。

The following command will write all cookies to a file named cookieand print out the CSRF token. Spring Security default token parameter name is _csrf, if you've changed it then you need to change grep csrfalso.

以下命令将所有 cookie 写入一个名为的文件cookie并打印出 CSRF 令牌。Spring Security 默认令牌参数名称是_csrf,如果您更改了它,那么您也需要更改grep csrf

curl --cookie-jar cookie -L http://localhost:8080/app/j_spring_security_check  | grep csrf

Then you can execute next command which will pass all cookies from file. Don't forget to replace |your_token_value|with an actual value which is printed out by the previous command (and _csrfparameter name if you've changed it).

然后您可以执行下一个命令,该命令将从文件中传递所有 cookie。不要忘记替换|your_token_value|为由上一个命令打印的实际值(_csrf如果您更改了参数名称,则为该值)。

curl --cookie cookie -d "j_username=admin&j_password=admin&_csrf=|your_token_value|" -L http://localhost:8080/app/j_spring_security_check

From Spring Security 3.x to 4.x

从 Spring Security 3.x 到 4.x

Note that in Spring Security 4.x default value for login-processing-urlchanged from /j_spring_security_checkto POST /login, default value for username-parameterchanged from j_usernameto usernameand default value for password-parameterchanged from j_passwordto password. If an application explicitly provides these attributes, no action is required for the migration.

请注意,在春季安全4.x的缺省值login-processing-url从更改/j_spring_security_check为POST /login,默认值username-parameter从改变j_usernameusername的并且默认值password-parameter从变化j_passwordpassword。如果应用程序明确提供这些属性,则迁移不需要任何操作。

回答by ortolanph

Based on the most voted answer, I wrote the following script:

根据得票最多的答案,我编写了以下脚本:

#!/usr/bin/env bash

curl --cookie-jar cookie -L http://localhost:PORT/secureDomain/secureURL

TOKEN=$( cat cookie | grep 'XSRF' | cut -f7 )

curl --cookie cookie -u admin:admin -d "_csrf=$TOKEN" -L http://localhost:PORT/secureDomain/secureURL

Works for Spring Security 4.

适用于 Spring Security 4。

回答by AlexR

You should configure spring to support basic authentication. Then add to your request the following header:

您应该配置 spring 以支持基本身份验证。然后将以下标头添加到您的请求中:

  • name: Authorization
  • value: base64(username:password)
  • 名称: Authorization
  • 价值: base64(username:password)

That means that user name and password should be cocatenated into one string with :as separator and then transformed using BASE64transformation.

这意味着用户名和密码应该用:作为分隔符连接成一个字符串,然后使用BASE64转换进行转换。

回答by cstroe

This script worked for me with Spring Boot 2.1.6 and Spring Security 5.1.5:

这个脚本适用于 Spring Boot 2.1.6 和 Spring Security 5.1.5:

# Obtain the CSRF token _plus_ the JSESSIONID cookie to go along with it.
export CSRF_TOKEN=$(curl -s -c cookies.txt -L http://localhost:8080/login | \
  grep -Eo "name=\"_csrf\" value=\"[0-9a-z-]+\"" | cut -d= -f3 | tr -d '"')

echo "Found csrf token: $CSRF_TOKEN"

# Login with the username and password, reading from (-b) and updating (-c) the cookie jar file.
curl -s -c cookies.txt -b cookies.txt -X POST \
     -F "username=admin" -F "password=password" -F "_csrf=$CSRF_TOKEN" http://localhost:8080/login

SESSION_ID=$(grep "JSESSIONID" cookies.txt | cut -f 7)
echo "Got session token: $SESSION_ID"

# Finally, execute authorized API action
curl -sL -b cookies.txt "http://localhost:8080/authorized/url"

回答by Rory

If CSRF is enabled, you need to capture the token value from the output of every request, in order to use it in the next one.

如果启用了 CSRF,您需要从每个请求的输出中捕获令牌值,以便在下一个请求中使用它。

BASEURL="http://localhost:8080/hac"
csrf=$(curl --silent --cookie-jar cookies.txt -L "$BASEURL/login.jsp" | egrep -o -m1 "[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}")
csrf=$(curl --silent --cookie cookies.txt --cookie-jar cookies.txt -L "$BASEURL/j_spring_security_check" --data "j_username=$USERNAME&j_password=$PASSWORD&_csrf=$csrf" | egrep -o -m1 "[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}" ) 

You can chain more commands in this manner, updating the value of $csrfevery time.

您可以以这种方式链接更多命令,$csrf每次更新 的值。

This worked on Spring security 3.

这适用于 Spring security 3。

回答by capocannoniere

It's not enough for me to use just -d options. Our web application is hosted by Tomcat, located in webapps/ROOT folder and have the following configuration:

仅使用 -d 选项对我来说是不够的。我们的 Web 应用程序由 Tomcat 托管,位于 webapps/ROOT 文件夹中,并具有以下配置:

<form-login login-page="/login.jsp"
    authentication-success-handler-ref="appAuthenticationSuccessHandler"
    authentication-failure-handler-ref="appAuthenticationFailureHandler"
    username-parameter="j_username" 
    password-parameter="j_password" 
    login-processing-url="/j_spring_security_check"/>

<csrf disabled="true"/>

<headers>
    <frame-options policy="SAMEORIGIN"/>
</headers>

The following works to send POST request to our web application (assuming Tomcat is listening on port 8080):

以下工作将 POST 请求发送到我们的 Web 应用程序(假设 Tomcat 正在侦听端口 8080):

curl -i -H "Content-Type: application/x-www-form-urlencoded" -c cookies.txt -H "Origin: http://localhost:8080/" -d "j_username=USERNAME&j_password=PASSWORD" -X POST http://localhost:8080/j_spring_security_check
curl -i -d @JSON_FILE -H "Content-Type: application/json" -H "Origin: http://localhost:8080/" -b cookies.txt -X POST http://localhost:8080/URL

Replace USERNAME, PASSWORD, JSON_FILE and URL with your own.

将 USERNAME、PASSWORD、JSON_FILE 和 URL 替换为您自己的。