Reputation: 11
I am trying to make a login from android using the library Okhttp3, but I can not keep the csrf token without it changing. I tried to get the header "X-CSRF-TOKEN" but I can not get it, I turned to the Jsoup library to parse the html and filter the _csrf to make the post request but the csrk token changes. I am using Spring boot + spring security, running on localhost. I need help because I search google and I have not found a solution.
<form class="col s12" id="formlogin" action="#" th:action="@{/logincheck}" th:method="POST">
<div class="row">
<div class="input-field col s12">
<i class="material-icons prefix">account_circle</i>
<input id="username" name="username" type="text" class="validate" th:required="required"/>
<label for="usuario">username</label>
</div>
</div>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
<div class="row">
<div class="input-field col s12">
<i class="material-icons prefix">lock</i>
<input id="password" name="password" type="password" class="validate" th:required="required"/>
<label for="password">password</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<button class="btn waves-effect waves-light pink col s12 m4 l4 xl4 right " type="submit"
name="action">
sign in
<i class="material-icons left">send</i>
</button>
</div>
</div>
Android Code:
final String url = "http://10.0.2.2:8080/login";
final OkHttpClient client;
client = new OkHttpClient();
Request request = new Request.Builder().url(url)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String html = response.body().string();
Document doc = Jsoup.parse(html);
String token = doc.select("input[name=_csrf]").val();
Log.e("token", token);
final RequestBody formBody = new FormBody.Builder()
.add("username", "username")
.add("password", "password")
.add("_csrf",token)
.build();
String urlpost = "http://10.0.2.2:8080/logincheck";
Request request2 = new Request.Builder()
.url(url).post(formBody).build();
Call call2 = client.newCall(request2);
call2.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.e("body", response.body().string());
}
});
}
});
Spring boot response with:
{"timestamp":1532156617366,"status":403,"error":"Forbidden","message":"Could not verify the provided CSRF token because your session was not found.","path":"/logincheck"}
Any ideas? Thank you
Upvotes: 1
Views: 1437
Reputation: 1036
Could not verify the provided CSRF token because your session was not found.
The problem is with your session, you need to save your spring security cookie session, here is an exemple of handle all cookies.
OkHttpClient client = new OkHttpClient.Builder()
.cookieJar(new CookieJar() {
private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
@Override
public void saveFromResponse(@NonNull HttpUrl url, @NonNull List<Cookie> cookies) {
cookieStore.put(url.host(), cookies);
}
@Override
public List<Cookie> loadForRequest(@NonNull HttpUrl url) {
List<Cookie> cookies = cookieStore.get(url.host());
return cookies != null ? cookies : new ArrayList<Cookie>();
}
})
.build();
Upvotes: 1