package org.restler.http.security.authorization;
import org.restler.client.RestlerException;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.stream.Stream;
/**
* The implementation that performs an HTTP POST request of login form data to obtain a session id.
*/
public class FormAuthorizationStrategy implements AuthorizationStrategy {
protected final URI url;
protected final String loginParameterName;
protected final String loginParameterValue;
protected final String passwordParameterName;
protected final String passwordParameterValue;
protected final String cookieName;
/**
* Creates a strategy that uses custom parameter names.
*/
public FormAuthorizationStrategy(URI url, String loginParameterName, String login, String passwordParameterName, String password, String cookieName) {
this.url = url;
this.loginParameterValue = login;
this.passwordParameterValue = password;
this.loginParameterName = loginParameterName;
this.passwordParameterName = passwordParameterName;
this.cookieName = cookieName;
}
@Override
public Object authorize() {
try {
byte[] postData = getPostData();
HttpURLConnection conn = (HttpURLConnection) url.toURL().openConnection();
submitForm(postData, conn);
return getCookies(conn).findAny().
map(s -> s.split("[=;]")[1]).
orElseThrow(() -> new RestlerException("Cookie " + cookieName + " not found in response on authorization request"));
} catch (IOException e) {
throw new RestlerException("Could not authorize request", e);
}
}
private byte[] getPostData() {
String urlParameters = loginParameterName + "=" + loginParameterValue + "&" +
passwordParameterName + "=" + passwordParameterValue;
return urlParameters.getBytes(StandardCharsets.UTF_8);
}
private HttpURLConnection submitForm(byte[] postData, HttpURLConnection conn) throws IOException {
conn.setDoOutput(true);
conn.setInstanceFollowRedirects(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("charset", "utf-8");
conn.setRequestProperty("Content-Length", Integer.toString(postData.length));
conn.setUseCaches(false);
try (DataOutputStream wr = new DataOutputStream(conn.getOutputStream())) {
wr.write(postData);
}
return conn;
}
private Stream<String> getCookies(HttpURLConnection conn) {
String headerName;
for (int i = 1; (headerName = conn.getHeaderFieldKey(i)) != null; i++) {
if (headerName.equals("Set-Cookie")) {
String cookie = conn.getHeaderField(i);
return Arrays.stream(cookie.split(";"));
}
}
return Stream.empty();
}
}