How to create a cookie and use it in HttpURLConnection? - java

I have the following python code which creates a cookie and adds it to the session. What would be the equivalent java code for it using HttpURLConnection? I basically want to do a HTTP POST request using the generated cookie.
session = requests.session()
session.auth = (username, password)
try:
token = session.get(SITEMINDER_URL % server, verify=False)
session.cookies.update(dict(SMSESSION=json.loads(token.content)['SMSESSION']))
except Exception as ex:
raise Exception("Failed in authenticating with siteminder", ex)
response = session.post(api_url, headers=headers, verify=False, json=data)

You would use something like this:
HttpURLConnection httpconn = < some source to get a HttpURLConnection >;
String cookieName = "SMSESSION"; // note this is the default but SM can use other prefixes
String cookieValue = < your token content >;
httpurl.setRequestProperty("Cookie", cookieName + "=" + cookieValue);
Also, from the javadocs: NOTE: HTTP requires all request properties which can legally have multiple instances with the same key to use a comma-separated list syntax which enables multiple properties to be appended into a single property
Which leads me to pointing out that using the HttpUrlConnection directly is really clumsy. I recommend you look at an HTTP client library such as Apache HTTP Client http://hc.apache.org/httpcomponents-client-ga/

In my opinion, you can just create an HttpUrlConnection object assigning a List of Cookies as follows:
List<String> cookies = new ArrayList<>();
//Or using a map With entries: Key and value for each cookie
cookies.add("User-Agent=MyUserAgent"); //etc...
URL site = new URL("https://myurl.com");
HttpsURLConnection conn = (HttpsURLConnection) site.openConnection();
for (String string: cookies) {
conn.setRequestProperty("Cookie", string);
}
However this is the simplest but not the best way to do so.

To get higher abstraction for Cookie use CookieManager and CookieStore classes. Here is an example:
HttpURLConnection connection
CookieManager cookieManager = new CookieManager();
HttpCookie cookie = new HttpCookie("cookieName","cookieValue");
cookieManager.getCookieStore().add(null,cookie);
connection.setRequestProperty("Cookie", String.join( ";", cookieManager.getCookieStore().getCookies()));

Try This:
URL url = new URL("http://www.example.com");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestProperty("Cookie", "name1=value1; name2=value2");
conn.connect();

Related

How do I go from getCookies() to a string in Java?

Input: I use HttpServletRequest class in Java that has getCookies().
Output: I need to set request's cookie field as a string:
// foo=123123;bar=222
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
String cookie = "foo=123123;bar=222"
connection.setRequestProperty("Cookie", cookie);
Is there a built in method to convert the output of getCookies() to string?
I do realize I can probably iterate over all cookies and create such a string manually, but it looks like I'm missing something.
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
String cookie = request.getHeader("Cookie");
connection.setRequestProperty("Cookie", cookie);
You can use the getHeader() method to get the Cookie header string:
String cookie = request.getHeader("Cookie");

Getting token from the URL in Java

In my project requirement, I was given a URL http://abc.grp.auth where it is accessible only in abc network. Am hitting this URL from browser and able to view the token in below format.
{"token" : "eqwqkldsdkldflanflna$%$!##"}
I want to get this token in java code within abc network as below.
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
But this code is giving 401 exception. This URL is taking the windows login, validating and sending the token. How can I achieve this in Java.
Thanks in Advance.
If there is used some kind of Basic authentication you can try to set special request header. Like this:
HttpGet httpget = new HttpGet(uri);
String encoding = Base64.encode(usr + ":" + psw);
httpget.setHeader("Authorization", "Basic " + encoding);

How to enable cookies when opening a URL's connection

I am trying to use the following code to get the redirected URL and then do some processing on it. But when I print the redirected link, it goes to a page that informs the absence of cookies. how is it possible to enable cookies while opening the url's connection?
String url = "http://dx.doi.org/10.1137/0210059";
URLConnection con = new URL( url ).openConnection();
con.getInputStream();
String redirctedURL= con.getURL().toString();
System.out.println(redirctedURL);
When using java UrlConnection's, you should handle the cookies by yourself, to read and set the cookies, you can use the setRequestProperty() and getHeaderField() of URLConnection.
The remaining part is parsing the cookies by yourself, an example how the can be done is as follows:
Map<String, String> cookie = new HashMap<>();
public URLConnection doConnctionWithCookies(URL url) {
StringBuilder builder = new StringBuilder();
builder.append("&");
for(Map.Entry<String,String> entry : cookie.entrySet()) {
builder.append(urlenEncode(entry.getKey()))
.append("=")
.append(urlenEncode(entry.getValue()))
.append("&");
}
builder.setLength(builder.length() - 1);
URLConnection con = url.openConnection();
con.setRequestProperty("Cookie", builder.toString());
con.connect();
// Parse cookie headers
List<String> setCookie = con.getHeaderFields().get("set-cookie");
// HTTP Spec state header fields MUST be case INsentive, I expet the above to work with all servers
if(setCookie == null)
return con;
// Parse all the cookies
for (String str : setCookie) {
String[] cookieKeyValue = str.split(";")[0].split("=",2);
if (cookieKeyValue.length != 2) {
continue;
}
cookie.put(urlenDecode(cookieKeyValue[0]), urlenDecode(cookieKeyValue[1]));
}
return con;
}
public String urlenEncode(String en) {
return URLEncoder.encode(en, "UTF-8");
}
public String urlenDecode(String en) {
return URLDecoder.decode(en, "UTF-8");
}
The above implementation is a very stupid and crude way of implementation cookies, while it works, it totally ignores the fact that cookies can also have a host parameter to prevent identification cookies be shared across multiple hosts.
A better way than doing it yourself can be using a library dedicated for the task like Apache HttpClient.

Servlet request to another servlet with authorization

I have tomcat server with some applications. This server uses standart j_secure_check auth. On another tomcat server I need to deploy application that must be some proxy to first server. So I need to invoke servlet from another servlet but first I need to do authentication with j_secure_check. Is it possible to do it programmely?
You need to grab the session cookie and pass it through on subsequent requests.
String url = "http://example.com/j_security_check?j_username=foo&j_password=bar";
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
if (connection.getResponseCode() == 200) { // 200 = OK, 401 = unauthorized
String cookie = connection.getHeaderField("Set-Cookie").split(";", 2)[0];
url = "http://example.com/somepage.jsp";
connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestProperty("Cookie", cookie);
InputStream input = connection.getInputStream();
// You can now write it to response.getOutputStream().
}

authenticate with ntlm (or kerberos) using java UrlConnection

I need to consume a rest web service with java, passing the credentials of a domain user account.
right now I'm doing it with classic asp
set xmlHttp = server.createObject( "msxml2.serverxmlhttp" )
xmlHttp.open method, url, false, domain & "\" & user, password
xmlHttp.send body
out = xmlHttp.responseText
set xmlHttp = nothing
and with asp.net
HttpWebRequest request = (HttpWebRequest) WebRequest.Create( url );
request.Credentials = new NetworkCredential(user, password, domain);
request.Method = WebRequestMethods.Http.Get
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
StreamReader outStream = new StreamReader( response.GetResponseStream(), Encoding.UTF8) ;
output = outStream.ReadToEnd();
how can I achieve this with java? Take into account that I'm not using the credentials of the currently logged user, I'm specifing the domain account (I have the password)
please tell me it's as easy as with classic asp and asp.net....
According to this page, you can use the built-in JRE classes, with the caveat that earlier versions of Java can only do this on a Windows machine.
However, if you are willing to live with a 3rd-party dependency, IMO Apache Commons HttpClient 3.x is the way to go. Here is the documentation for using authentication, including NTLM. In general, HttpClient is a much more functional library.
The latest version of HttpClient is 4.0, but apparently this version does not support NTLM this version requires a tiny bit of extra work.
Here is what I think the code would look like, although I haven't tried it:
HttpClient httpClient = new HttpClient();
httpClient.getState().setCredentials(AuthScope.ANY, new NTCredentials(user, password, hostPortionOfURL, domain));
GetMethod request = new GetMethod(url);
BufferedReader reader = new InputStreamReader(request.getResponseBodyAsStream());
Good luck.
A compatible solution for java.net.URLStreamHandler and java.net.URL is com.intersult.net.http.NtlmHandler:
NtlmHandler handler = new NtlmHandler();
handler.setUsername("domain\\username");
handler.setPassword("password");
URL url = new URL(null, urlString, handler);
URLConnection connection = url.openConnection();
You also can use java.net.Proxy within url.openConnection(proxy).
Use Maven-Dependency:
<dependency>
<groupId>com.intersult</groupId>
<artifactId>http</artifactId>
<version>1.1</version>
</dependency>
Take a look at the SpnegoHttpURLConnection class in the SPNEGO HTTP Servlet Filter project. This project has some examples as well.
This project has a client library that pretty much does what you are doing in your example.
Take a look this example from the javadoc...
public static void main(final String[] args) throws Exception {
final String creds = "dfelix:myp#s5";
final String token = Base64.encode(creds.getBytes());
URL url = new URL("http://medusa:8080/index.jsp");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty(Constants.AUTHZ_HEADER
, Constants.BASIC_HEADER + " " + token);
conn.connect();
System.out.println("Response Code:" + conn.getResponseCode());
}

Categories