I am working on a springMVC project in which the user authentication is based on spring security.
the idea is to have a mobile (android) application to be able to se
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.
Use cURL like this:
curl -d j_username=admin -d j_password=admin -L http://localhost:8080/app/j_spring_security_check
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.
The following command will write all cookies to a file named cookie and print out the CSRF token. Spring Security default token parameter name is _csrf, if you've changed it then you need to change grep csrf also.
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 _csrf parameter name if you've changed it).
curl --cookie cookie -d "j_username=admin&j_password=admin&_csrf=|your_token_value|" -L http://localhost:8080/app/j_spring_security_check
Note that in Spring Security 4.x default value for login-processing-url changed from /j_spring_security_check to POST /login, default value for username-parameter changed from j_username to username and default value for password-parameter changed from j_password to password. If an application explicitly provides these attributes, no action is required for the migration.
You should configure spring to support basic authentication. Then add to your request the following header:
Authorizationbase64(username:password)That means that user name and password should be cocatenated into one string with : as separator and then transformed using BASE64 transformation.
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.
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 $csrf every time.
This worked on Spring security 3.
This script worked for me with Spring Boot 2.1.6 and 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"
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:
<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):
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.