How to set the jsessionid cookie with jsoup? - java

I have a problem with the following test method for authentication to the site of the university .
I'm using Jsoup and I can not get the cookies (jsessionid) to login .
The method is this :
public static void Authentication() {
String strURL = "https://www.studenti.ict.uniba.it/esse3/auth/Logon.do";
String strUserId = "prova";
String strPasword = "prova";
String authString = strUserId + ":" + strPasword;
String encodedString = new String( Base64.encodeBase64(authString.getBytes()) );
try{
Response response = Jsoup.connect(strURL)
.header("Authorization", "Basic " + encodedString)
.method(org.jsoup.Connection.Method.GET)
.timeout(30000)
.execute();
System.out.println(response.parse());
System.out.println("Autenticato");
}catch (IOException e){
e.printStackTrace();
}
}

You can retrieve the cookie creating another request to the home of the website.
package com.github.davidepastore.stackoverflow38768839;
import java.io.IOException;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
/**
* Stackoverflow 38768839 answer.
*
*/
public class App {
private static final String COOKIE_NAME = "JSESSIONID";
public static void main(String[] args) throws IOException {
// Step 1 - Get the cookie
String homeURL = "https://www.studenti.ict.uniba.it/esse3/Home.do";
Response response = Jsoup.connect(homeURL).execute();
String jsessionid = response.cookie(COOKIE_NAME);
System.out.println(COOKIE_NAME + " cookie: " + jsessionid);
// Step 2 - Try to login
String strURL = "https://www.studenti.ict.uniba.it/esse3/auth/Logon.do";
String strUserId = "prova";
String strPasword = "prova";
String authString = strUserId + ":" + strPasword;
String encodedString = new String(Base64.encodeBase64(authString
.getBytes()));
try {
response = Jsoup.connect(strURL)
.header("Authorization", "Basic " + encodedString)
.cookie(COOKIE_NAME, jsessionid)
.method(org.jsoup.Connection.Method.GET).timeout(30000)
.execute();
System.out.println(response.parse());
System.out.println("Autenticato");
} catch (IOException e) {
e.printStackTrace();
}
}
}

Related

Oauth2 authentication with Private Key C#

I am attempting to authenticate via Oauth2 to an API however, I had trouble creating the request because of a private key. I was provided a sample code by the vendor which is Java and I converted it over to C# but I can't seem to get the private key into the JWT request.
Side note, the client, secret and URL's have been masked for this example.
Working Java code
public class Test {
private static final String RSSO_URL = "https://test-dev.onbmc.com/rsso";
private static final String CLIENT_ID = "36fa1bd2-6f92-408e-b7e4-dd4df7a9cfaz";
private static final String CLIENT_SECRET = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjBgEAAoIBAQC169y6kMo/hZ/3oRFKwU1bxmzCJhWgH54j3Vn1JW4SmgO3rH5bHkVcqt03aaQmQms/fBDe2SlCKS3pxH6pVXB8aKQj8EOPWstwjvjsQrCiKLyqAMbc6E7IBVp1Dq77wFtv+P3fk80/9OA4a6ahr9Dp14+3YawyOU/5Ebf/i2WwKkySTgQOGLXvk3+LtsoODubMAnyJYWb6e+Uhrbn/vSqlGDDjGtANahw5oWjqFy8IYFttzMNB0VF2+sKIzGvQ+Izlo+u4wTgN7pB5g8bSz9Q92QzeWRVh7OCaef3L0i6Ozp3rO46bo3+G+QJdn4UKPcYMubtNGMC511aDU8Yay4IPAgMBAAECggEAMGTwMQk3ZDKN3XgRe4t0osdCNlufQRtoHC5UMeylHXmvJ3tRmbexx/cdqwgxTKQ6l4bPjhjC6wC9YASPlUhPRikoEQ9nSYljuSuveFo9VsXzel3+iOGbo4YZDC69yebf7CeWkZVl8m+X/ipVB4oXzz0y1Bu9jRbF+YIHKonQoU4MgsQQrYa8J8cSx75fkByNj9HdQtd99aK2jsMSArQ1R+PnUjDWpxlZBAowRmaw6iPWJbHmhLUSyrIvBJOo3fNZlXPS/S8jL5s0n137K640WFjy5LBakooHqmjfaFk/5z5krBaWaehDXU2AXLcKRQi946QhC99leSxBTastfjIh0QKBgQDZDZRME+GvJwnnMOht0BuVjcazCkY5LcfxD4vwQeK8p7zyqaxcvNu0+0ulKy+kqP6d/Q1ITIXlQDEA8a2d/iiOhSI84Y/g9az9ZSvRHH/Z5gRdRrymZJcqCzzpxjqi0uvaKOQUWwrKthnxnAS+1oJPlqOc1CtO/j4qzc7I2D7VxQKBgQDWkH5YTYLM5EWos1zdEmVqnIrUYbKlkyHJWSYnC/f5VsOoVEV4R1012w3HfwPceRjYOxeUtHTPN3MB9B5Xn5d3oBFBk8Md9phD5St9KXGakPY0sWC1yFEg8/Zr9fVm5jren6tJQmhKEeiV6DtueqQShEVVIEJixrQQkwFQ4SvJwwKBgCKh+Qyei38gEoNyGVQURaJ6Sb8dn5DWDjYXjfOa/6usdAigLCFr/P6Grk4/cs2qLV5WFz13AFJRCMCmz1YLTLtY4Nqn/wYdDSotb21hR8Ej44Rimg1OtZP+0QxYFdkPIJThu2rIEBPCNKeJhnRQ0+ARIDAQ5ownIxI/XoRLhNMlAoGAQl9mRgiMKrd+eOYrFtPm/Wi5ZWNncOKns/JY5AFGzyGw2rRe3QsuYUeG5qx61Eu9jL4S2FROQf+EGxmZ/T8ICuBAFkoQNIegqHgO0OPuGYM4NiqcoP77Ybc2BkWKiS81DMLVqI7bVfZePWkeYVmcwYGbNO8KuiV/dBUVdiCBfCMCgYEAoUvJefM+ENuhnxrH6A+4lEH4CI64gkQ5tkF3JeAMCiIov5OEuJx+65ULXeAwhrvcLB3Ginh0hI2RNQGV5iOeu0+sHmNA8yt0ivoCweNxiPM0RGWcH5FFBzI88WlGbMl0eg3NHt9jV5yTwNJYonjPFgCUkasaclhDZlZxgN891LA=";
private static final String PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDhY8LmtZ7fZOAX\n" +
"gw7SKyHzZ6Q0H0ss+3cJ7NEkEofUN2IfycE5u6eQb396uN16bzZaQcwnK9He3xwk\n" +
"3H4wWLzOUlhfuo87bJ34VdNBa1hfAk4iyk1ZgyufGy6MKgwycXhIl9wibX/f1fmF\n" +
"khHnkXVyYY5hSewceCT51bMzcv+psGf7KkN8jh/bRb+/GGfxVy13GKfFTzwY1Y7G\n" +
"SH7J00EaUQsEVCbkV3HK185v6t1fb2faao2imgj/Xqzc/DBbConBoF8/89SJSuf9\n" +
"1RVGdctNwqerMOUoDJ2ynHNqhbO3POq6O1XMi0c75q4xdtrNWLa8A5ONPUXDgIo/\n" +
"Ddwj1tTNAgMBAAECggEACG83yXNtfRWkzyxv3wyPKjEsM2kiYo4Mf9oVX4C0BYyH\n" +
"BwKBURxFIoIRprGJVD4aLhl9PtAEfA8kWfrIXB3N/viU5wwvtP0VEkh/7dhLB88p\n" +
"xmKEr39ZoAwf203tg+u8IRdRvRYU7Xbv7gAv3FcUqpGdBuYByHT0iUbmfFvm1l46\n" +
"HD2ypQFKr3a536w2sFR6XKK6G+Al69lyg0Hg4jXmmDMo+xoxqrJeYxT11G6iBWmy\n" +
"UXKDdOVx4BarT+dcnCUP0yahmQz08XObNDNphWG/aOFF6cMyU4hNkK9q0AC6sAzQ\n" +
"89dTVTPErjEJcJZ16mtI9nv5u4VKfbL1mU+ivb4pQQKBgQD+FdFx+BKojVYilT1i\n" +
"WMbXabRtm03NezgzSgIDKTxiewoQAy+n+InGPy2pz18/1DP8kasnsU8VZvRM7dXV\n" +
"lJTXrqOM/lMN8vMt7/fpz0PYEDP6Qz7CLxA0xEcW2qFR4RAQzq3xXIH/7M4VUZzD\n" +
"qzznD8aJaG5fsSExt7aITU984QKBgQDjFpVsxDxF3YZBhonuNaSrvTdDwbMqdCLT\n" +
"ZoXUL+4aKY78cD2FCfdqJ5O1uyrAqgCgjouiVnNRzDy3qSSGxaiwpI3+FA8cCNiS\n" +
"W0CE/urjDDeXU0Q5jDSBdljBF23wf9mNmXpgXSHfgQVTIiVMVD5tNhU/ORu5PXzo\n" +
"SdW67DLJbQKBgDYYbRQnrclG9hy8y2nh3svEDI70bq4d2tRIoG8N23ZYHcdU9lN7\n" +
"vdGAZ/dsWCodwse2N8tmm6DB36d1R36GeL4Gx3lgOEyS+iVAnvafkyEwKfDRWk47\n" +
"eObTFxONjqUBFsuNRUlK2b6kKygszQR3s6q6GBnvKviinJ+aLnmMhCzhAoGBAKLC\n" +
"gP6f87/kcmFsiFePYyMkTwPlRQDclEloZesbH1DpEG6mE7HS3t3a1+ec6puEPUbW\n" +
"ZAZKaATsmWgZdvCRosJYbtz4i4vQW0kq1id8feWV1BJJv9BvSQKxTBO5Mzb4q3jt\n" +
"0+RVW/3Rf3uCMbFvf/7OkJPr3o76HxhuMx3yRMRRAoGAZiFbVjd3EKUdyE0O3QSh\n" +
"46KzTdT0ENhBlN2dpCdJjHJm3Lcxa7uY4sxa8NqYUW0NO2qRSd42IKfGX3qqi7wf\n" +
"+rUFFixCzQOoucR/ekTw+542Nbc0QejAQ0SUDwgHWX8L8Yi+W3UsBL2YLLIw5ged\n" +
"7Ghsl3cgdKPMlAh1kzxsWic=";
public static JsonPath getOAuthToken() throws InvalidKeySpecException, NoSuchAlgorithmException {
return with().log().all()
.contentType(ContentType.URLENC)
.formParam("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer")
.formParam("assertion", getClientJwt())
.formParam("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer")
.formParam("redirect_uri", "https://test-dev-restapi.us.onbmc.com/api/jwt/login")
.formParam("audience", "test-dev-restapi.us.onbmc.com")
.formParam("client_id", CLIENT_ID)
.formParam("client_secret", CLIENT_SECRET)
.when()
.post(RSSO_URL + "/oauth2/token")
.then()
.log().all()
.statusCode(HttpURLConnection.HTTP_OK)
.extract()
.response()
.getBody()
.jsonPath();
}
static String getClientJwt() throws InvalidKeySpecException, NoSuchAlgorithmException {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, 1);
return Jwts.builder()
.signWith(loadPrivateKey(PRIVATE_KEY))
.setIssuer(CLIENT_ID)
.setSubject("JWT")
.setAudience("test-dev-restapi.us.onbmc.com")
.setExpiration(calendar.getTime())
.compact();
}
static PrivateKey loadPrivateKey(String privateKeyStr) throws NoSuchAlgorithmException, InvalidKeySpecException {
KeyFactory kf = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(privateKeyStr));
return kf.generatePrivate(keySpecPKCS8);
}
//#Test
public void getOauthAccessTokenUsingJwtGrantType() throws Exception {
System.out.println("Trying to get OAuth Access and Refresh tokens");
JsonPath response = getOAuthToken();
System.out.println("Access Token = " + response.getString("access_token"));
System.out.println("Refresh Token = " + response.getString("refresh_token"));
System.out.println("Expires in = " + response.getString("expires_in"));
System.out.println("OAuth2 Token was successfully obtained.");
}
public static void main(String str[]) throws Exception {
JsonPath response = getOAuthToken();
}
}
Converted Java code to C#
using java.security;
using java.security.spec;
using JWT;
using JWT.Algorithms;
using JWT.Builder;
using JWT.Serializers;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using RestSharp;
using RestSharp.Authenticators;
using System;
using System.Buffers.Text;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
namespace TestApp
{
class Program
{
private static string RSSO_URL = "https://test-dev.onbmc.com/rsso";
`enter code here`private static string CLIENT_ID = "36fa1bd2-6f92-408e-b7e4-dd4df7a9cfaz";
private static string CLIENT_SECRET = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjBgEAAoIBAQC169y6kMo/hZ/3oRFKwU1bxmzCJhWgH54j3Vn1JW4SmgO3rH5bHkVcqt03aaQmQms/fBDe2SlCKS3pxH6pVXB8aKQj8EOPWstwjvjsQrCiKLyqAMbc6E7IBVp1Dq77wFtv+P3fk80/9OA4a6ahr9Dp14+3YawyOU/5Ebf/i2WwKkySTgQOGLXvk3+LtsoODubMAnyJYWb6e+Uhrbn/vSqlGDDjGtANahw5oWjqFy8IYFttzMNB0VF2+sKIzGvQ+Izlo+u4wTgN7pB5g8bSz9Q92QzeWRVh7OCaef3L0i6Ozp3rO46bo3+G+QJdn4UKPcYMubtNGMC511aDU8Yay4IPAgMBAAECggEAMGTwMQk3ZDKN3XgRe4t0osdCNlufQRtoHC5UMeylHXmvJ3tRmbexx/cdqwgxTKQ6l4bPjhjC6wC9YASPlUhPRikoEQ9nSYljuSuveFo9VsXzel3+iOGbo4YZDC69yebf7CeWkZVl8m+X/ipVB4oXzz0y1Bu9jRbF+YIHKonQoU4MgsQQrYa8J8cSx75fkByNj9HdQtd99aK2jsMSArQ1R+PnUjDWpxlZBAowRmaw6iPWJbHmhLUSyrIvBJOo3fNZlXPS/S8jL5s0n137K640WFjy5LBakooHqmjfaFk/5z5krBaWaehDXU2AXLcKRQi946QhC99leSxBTastfjIh0QKBgQDZDZRME+GvJwnnMOht0BuVjcazCkY5LcfxD4vwQeK8p7zyqaxcvNu0+0ulKy+kqP6d/Q1ITIXlQDEA8a2d/iiOhSI84Y/g9az9ZSvRHH/Z5gRdRrymZJcqCzzpxjqi0uvaKOQUWwrKthnxnAS+1oJPlqOc1CtO/j4qzc7I2D7VxQKBgQDWkH5YTYLM5EWos1zdEmVqnIrUYbKlkyHJWSYnC/f5VsOoVEV4R1012w3HfwPceRjYOxeUtHTPN3MB9B5Xn5d3oBFBk8Md9phD5St9KXGakPY0sWC1yFEg8/Zr9fVm5jren6tJQmhKEeiV6DtueqQShEVVIEJixrQQkwFQ4SvJwwKBgCKh+Qyei38gEoNyGVQURaJ6Sb8dn5DWDjYXjfOa/6usdAigLCFr/P6Grk4/cs2qLV5WFz13AFJRCMCmz1YLTLtY4Nqn/wYdDSotb21hR8Ej44Rimg1OtZP+0QxYFdkPIJThu2rIEBPCNKeJhnRQ0+ARIDAQ5ownIxI/XoRLhNMlAoGAQl9mRgiMKrd+eOYrFtPm/Wi5ZWNncOKns/JY5AFGzyGw2rRe3QsuYUeG5qx61Eu9jL4S2FROQf+EGxmZ/T8ICuBAFkoQNIegqHgO0OPuGYM4NiqcoP77Ybc2BkWKiS81DMLVqI7bVfZePWkeYVmcwYGbNO8KuiV/dBUVdiCBfCMCgYEAoUvJefM+ENuhnxrH6A+4lEH4CI64gkQ5tkF3JeAMCiIov5OEuJx+65ULXeAwhrvcLB3Ginh0hI2RNQGV5iOeu0+sHmNA8yt0ivoCweNxiPM0RGWcH5FFBzI88WlGbMl0eg3NHt9jV5yTwNJYonjPFgCUkasaclhDZlZxgN891LA=";
private static string PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDhY8LmtZ7fZOAX\n" +
"gw7SKyHzZ6Q0H0ss+3cJ7NEkEofUN2IfycE5u6eQb396uN16bzZaQcwnK9He3xwk\n" +
"3H4wWLzOUlhfuo87bJ34VdNBa1hfAk4iyk1ZgyufGy6MKgwycXhIl9wibX/f1fmF\n" +
"khHnkXVyYY5hSewceCT51bMzcv+psGf7KkN8jh/bRb+/GGfxVy13GKfFTzwY1Y7G\n" +
"SH7J00EaUQsEVCbkV3HK185v6t1fb2faao2imgj/Xqzc/DBbConBoF8/89SJSuf9\n" +
"1RVGdctNwqerMOUoDJ2ynHNqhbO3POq6O1XMi0c75q4xdtrNWLa8A5ONPUXDgIo/\n" +
"Ddwj1tTNAgMBAAECggEACG83yXNtfRWkzyxv3wyPKjEsM2kiYo4Mf9oVX4C0BYyH\n" +
"BwKBURxFIoIRprGJVD4aLhl9PtAEfA8kWfrIXB3N/viU5wwvtP0VEkh/7dhLB88p\n" +
"xmKEr39ZoAwf203tg+u8IRdRvRYU7Xbv7gAv3FcUqpGdBuYByHT0iUbmfFvm1l46\n" +
"HD2ypQFKr3a536w2sFR6XKK6G+Al69lyg0Hg4jXmmDMo+xoxqrJeYxT11G6iBWmy\n" +
"UXKDdOVx4BarT+dcnCUP0yahmQz08XObNDNphWG/aOFF6cMyU4hNkK9q0AC6sAzQ\n" +
"89dTVTPErjEJcJZ16mtI9nv5u4VKfbL1mU+ivb4pQQKBgQD+FdFx+BKojVYilT1i\n" +
"WMbXabRtm03NezgzSgIDKTxiewoQAy+n+InGPy2pz18/1DP8kasnsU8VZvRM7dXV\n" +
"lJTXrqOM/lMN8vMt7/fpz0PYEDP6Qz7CLxA0xEcW2qFR4RAQzq3xXIH/7M4VUZzD\n" +
"qzznD8aJaG5fsSExt7aITU984QKBgQDjFpVsxDxF3YZBhonuNaSrvTdDwbMqdCLT\n" +
"ZoXUL+4aKY78cD2FCfdqJ5O1uyrAqgCgjouiVnNRzDy3qSSGxaiwpI3+FA8cCNiS\n" +
"W0CE/urjDDeXU0Q5jDSBdljBF23wf9mNmXpgXSHfgQVTIiVMVD5tNhU/ORu5PXzo\n" +
"SdW67DLJbQKBgDYYbRQnrclG9hy8y2nh3svEDI70bq4d2tRIoG8N23ZYHcdU9lN7\n" +
"vdGAZ/dsWCodwse2N8tmm6DB36d1R36GeL4Gx3lgOEyS+iVAnvafkyEwKfDRWk47\n" +
"eObTFxONjqUBFsuNRUlK2b6kKygszQR3s6q6GBnvKviinJ+aLnmMhCzhAoGBAKLC\n" +
"gP6f87/kcmFsiFePYyMkTwPlRQDclEloZesbH1DpEG6mE7HS3t3a1+ec6puEPUbW\n" +
"ZAZKaATsmWgZdvCRosJYbtz4i4vQW0kq1id8feWV1BJJv9BvSQKxTBO5Mzb4q3jt\n" +
"0+RVW/3Rf3uCMbFvf/7OkJPr3o76HxhuMx3yRMRRAoGAZiFbVjd3EKUdyE0O3QSh\n" +
"46KzTdT0ENhBlN2dpCdJjHJm3Lcxa7uY4sxa8NqYUW0NO2qRSd42IKfGX3qqi7wf\n" +
"+rUFFixCzQOoucR/ekTw+542Nbc0QejAQ0SUDwgHWX8L8Yi+W3UsBL2YLLIw5ged\n" +
"7Ghsl3cgdKPMlAh1kzxsWic=";
static void Main(string[] args)
{
try
{
//create RestSharp client and POST request object
var client = new RestClient(RSSO_URL + "/oauth2/token");
var request = new RestRequest();
request.Method = Method.Post;
client.Authenticator = new HttpBasicAuthenticator(CLIENT_ID, CLIENT_SECRET);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer");
request.AddParameter("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer");
request.AddParameter("redirect_uri", "https://test-dev-restapi.us.onbmc.com/api/jwt/login");
request.AddParameter("audience", "test-dev-restapi.us.onbmc.com");
request.AddParameter("client_id", CLIENT_ID);
request.AddParameter("client_secret", CLIENT_SECRET);
request.AddParameter("assertion", Program.getClientJwt());
RestResponse response = client.Execute(request);
//return an AccessToken
var poo = JsonConvert.DeserializeObject(response.Content);
}
catch(Exception ex)
{
}
}
public static string getClientJwt() {
DateTime exp = DateTime.UtcNow.AddYears(1);
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(PRIVATE_KEY));
var signIn = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature);
var token = new JwtSecurityToken(CLIENT_ID, "miamidade-dev-restapi.us.onbmc.com", null, null, DateTime.UtcNow.AddYears(1), signIn);
return new JwtSecurityTokenHandler().WriteToken(token);
}
public static PrivateKey loadPrivateKey(String privateKeyStr)
{
KeyFactory kf = KeyFactory.getInstance("RSA");
byte[] decodedBytes = Convert.FromBase64String(privateKeyStr);
PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(decodedBytes);
return kf.generatePrivate(keySpecPKCS8);
}
}
}
When I send the request, I get the error
{"error_description":"Not valid request, JWT is rejected","error":"invalid_grant"}

How to store result of exchange.getRequestURI().getQuery() in variable and use it to get authorization code

I'm trying to implement this stage of project - https://hyperskill.org/projects/62/stages/337/implement.
I need to store result of String code = exchange.getRequestURI().getQuery(); in a variable and use it in POST request.
POST(HttpRequest.BodyPublishers.ofString("client_id=" + CLIENT_ID + "&client_secret=" + CLIENT_SECRET+ "&grant_type=" + GRANT_TYPE + "&code=" + CODE + "&redirect_uri=" + REDIRECT_URI))
But I can't do that, because of it doesn't store in a vairable outside of server.createContext.
Maybe I'm trying to do wrong thing? Can anyone help me?
private static final String CLIENT_ID = "da072c60fcee469e8b0f4140aa4480d5";
private static final String CLIENT_SECRET = "8ada13093c704487b57c3a660448884e";
private static final String AUTHORIZE_ADDRESS = "https://accounts.spotify.com/authorize";
private static final String RESPONSE_TYPE = "code";
private static final String TOKEN_ADDRESS = "https://accounts.spotify.com/api/token";
private static final String GRANT_TYPE = "authorization_code";
private static final String CODE = "";
private static final String REDIRECT_URI = "http://localhost:8080";
private static final String ANSWER_DENIED_ACCESS = "Please, provide access for application.";
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
boolean successfulAccess = false;
while (sc.hasNext()) {
String input = sc.next();
switch (input) {
case "auth":
server();
request();
successfulAccess = true;
System.out.println("---SUCCESS---");
break;
}
}
}
private static void server() throws IOException {
HttpServer server = HttpServer.create();
server.bind(new InetSocketAddress(8080), 0);
server.start();
System.out.println("use this link to request the access code:");
System.out.println(AUTHORIZE_ADDRESS
+ "?client_id=" + CLIENT_ID
+ "&redirect_uri=" + REDIRECT_URI
+ "&response_type=" + RESPONSE_TYPE);
System.out.println("waiting for code...");
server.createContext("/",
exchange -> {
String code = exchange.getRequestURI().getQuery();
String result = "";
String answer = "";
if (code.contains("code")) {
result = "Got the code. Return back to your program.";
answer = "code received";
} else {
result = "Not found authorization code. Try again.";
answer = "code didn't received";
}
exchange.sendResponseHeaders(200, result.length());
exchange.getResponseBody().write(result.getBytes());
exchange.getResponseBody().close();
System.out.println(answer);
}
);
server.stop(10);
}
private static void request() throws IOException, InterruptedException {
System.out.println("making http request for access_token...");
HttpRequest request = HttpRequest.newBuilder()
.POST(HttpRequest.BodyPublishers.ofString(
"client_id=" + CLIENT_ID
+ "&client_secret=" + CLIENT_SECRET
+ "&grant_type=" + GRANT_TYPE
+ "&code=" + CODE
+ "&redirect_uri=" + REDIRECT_URI))
.header("Content-Type", "application/x-www-form-urlencoded")
.uri(URI.create(TOKEN_ADDRESS))
.build();
HttpClient client = HttpClient.newBuilder().build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("response:");
System.out.println(response.body());
}
}```
I need while cycle with Thread.sleep, than you can normally store code in variable. Like this:
exchange -> {
String code = exchange.getRequestURI().getQuery();
String result = "";
String answer = "";
if (code != null && code.contains("code")) {
CODE = code.substring(5);
result = "Got the code. Return back to your program.";
answer = "code received";
} else {
result = "Not found authorization code. Try again.";
answer = "code not received";
}
exchange.sendResponseHeaders(200, result.length());
exchange.getResponseBody().write(result.getBytes());
exchange.getResponseBody().close();
System.out.println(answer);
}
);
while (CODE.equals("")) {
Thread.sleep(10);
}
server.stop(10);```

Crawl all the links of a page that is password protected

I am crawling a page that requires username and password for authentication. And I successfully got the 200 OK response back from the server for that page when I passed my username and password in the code. But it gets stop as soon as it gives the 200 OK response back. It doesn't move forward in to that page after authentication to crawl all those links that are there in that page. And this crawler is taken from http://code.google.com/p/crawler4j/.
This is the code where I am doing the authentication stuff...
public class MyCrawler extends WebCrawler {
Pattern filters = Pattern.compile(".*(\\.(css|js|bmp|gif|jpe?g"
+ "|png|tiff?|mid|mp2|mp3|mp4" + "|wav|avi|mov|mpeg|ram|m4v|pdf"
+ "|rm|smil|wmv|swf|wma|zip|rar|gz))$");
List<String> exclusions;
public MyCrawler() {
exclusions = new ArrayList<String>();
//Add here all your exclusions
exclusions.add("http://www.dot.ca.gov/dist11/d11tmc/sdmap/cameras/cameras.html");
}
public boolean shouldVisit(WebURL url) {
String href = url.getURL().toLowerCase();
DefaultHttpClient client = null;
try
{
System.out.println("----------------------------------------");
System.out.println("WEB URL:- " +url);
client = new DefaultHttpClient();
client.getCredentialsProvider().setCredentials(
new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM),
new UsernamePasswordCredentials("test", "test"));
client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
for(String exclusion : exclusions){
if(href.startsWith(exclusion)){
return false;
}
}
if (href.startsWith("http://") || href.startsWith("https://")) {
return true;
}
HttpGet request = new HttpGet(url.toString());
System.out.println("----------------------------------------");
System.out.println("executing request" + request.getRequestLine());
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
System.out.println(response.getStatusLine());
}
catch(Exception e) {
e.printStackTrace();
}
return false;
}
public void visit(Page page) {
System.out.println("hello");
int docid = page.getWebURL().getDocid();
String url = page.getWebURL().getURL();
System.out.println("Page:- " +url);
String text = page.getText();
List<WebURL> links = page.getURLs();
int parentDocid = page.getWebURL().getParentDocid();
System.out.println("Docid: " + docid);
System.out.println("URL: " + url);
System.out.println("Text length: " + text.length());
System.out.println("Number of links: " + links.size());
System.out.println("Docid of parent page: " + parentDocid);
}
}
And this is my Controller class
public class Controller {
public static void main(String[] args) throws Exception {
CrawlController controller = new CrawlController("/data/crawl/root");
//And I want to crawl all those links that are there in this password protected page
controller.addSeed("http://search.somehost.com/");
controller.start(MyCrawler.class, 20);
controller.setPolitenessDelay(200);
controller.setMaximumCrawlDepth(2);
}
}
Anything wrong I am doing....
As described in http://code.google.com/p/crawler4j/ the shoudVisit() function should only return true or false. But in your code, this function is also fetching the content of the page which is wrong. The current version of crawler4j (3.0) doesn't support crawling of password-protected pages.

XMPP with Java Asmack library supporting X-FACEBOOK-PLATFORM

I'm trying to make a Facebook Chat on Android with the Smack library. I've read the Chat API from Facebook, but I cannot understand how I have to authenticate with Facebook using this library.
Can anyone point me how to accomplish this?
Update: According to the no.good.at.coding answer, I have this code adapted to the Asmack library. All works fine except I receive as response to the login: not-authorized. Here is the code I use:
public class SASLXFacebookPlatformMechanism extends SASLMechanism
{
private static final String NAME = "X-FACEBOOK-PLATFORM";
private String apiKey = "";
private String applicationSecret = "";
private String sessionKey = "";
/**
* Constructor.
*/
public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication)
{
super(saslAuthentication);
}
#Override
protected void authenticate() throws IOException, XMPPException
{
getSASLAuthentication().send(new AuthMechanism(NAME, ""));
}
#Override
public void authenticate(String apiKeyAndSessionKey, String host,
String applicationSecret) throws IOException, XMPPException
{
if (apiKeyAndSessionKey == null || applicationSecret == null)
{
throw new IllegalArgumentException("Invalid parameters");
}
String[] keyArray = apiKeyAndSessionKey.split("\\|", 2);
if (keyArray.length < 2)
{
throw new IllegalArgumentException(
"API key or session key is not present");
}
this.apiKey = keyArray[0];
Log.d("API_KEY", apiKey);
this.applicationSecret = applicationSecret;
Log.d("SECRET_KEY", applicationSecret);
this.sessionKey = keyArray[1];
Log.d("SESSION_KEY", sessionKey);
this.authenticationId = sessionKey;
this.password = applicationSecret;
this.hostname = host;
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
this.sc =
Sasl.createSaslClient(mechanisms, null, "xmpp", host, props,
this);
authenticate();
}
#Override
protected String getName()
{
return NAME;
}
#Override
public void challengeReceived(String challenge) throws IOException
{
byte[] response = null;
if (challenge != null)
{
String decodedChallenge = new String(Base64.decode(challenge));
Log.d("DECODED", decodedChallenge);
Map<String, String> parameters = getQueryMap(decodedChallenge);
String version = "1.0";
String nonce = parameters.get("nonce");
String method = parameters.get("method");
long callId = new GregorianCalendar().getTimeInMillis() / 1000L;
String sig =
"api_key=" + apiKey + "call_id=" + callId + "method="
+ method + "nonce=" + nonce + "session_key="
+ sessionKey + "v=" + version + applicationSecret;
try
{
sig = md5(sig);
sig = sig.toUpperCase();
} catch (NoSuchAlgorithmException e)
{
throw new IllegalStateException(e);
}
String composedResponse =
"api_key=" + URLEncoder.encode(apiKey, "utf-8")
+ "&call_id=" + callId + "&method="
+ URLEncoder.encode(method, "utf-8") + "&nonce="
+ URLEncoder.encode(nonce, "utf-8")
+ "&session_key="
+ URLEncoder.encode(sessionKey, "utf-8") + "&v="
+ URLEncoder.encode(version, "utf-8") + "&sig="
+ URLEncoder.encode(sig, "utf-8");
Log.d("COMPOSED", composedResponse);
response = composedResponse.getBytes("utf-8");
}
String authenticationText = "";
if (response != null)
{
authenticationText =
Base64.encodeBytes(response, Base64.DONT_BREAK_LINES);
}
// Send the authentication to the server
getSASLAuthentication().send(new Response(authenticationText));
}
private Map<String, String> getQueryMap(String query)
{
Map<String, String> map = new HashMap<String, String>();
String[] params = query.split("\\&");
for (String param : params)
{
String[] fields = param.split("=", 2);
map.put(fields[0], (fields.length > 1 ? fields[1] : null));
}
return map;
}
private String md5(String text) throws NoSuchAlgorithmException,
UnsupportedEncodingException
{
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(text.getBytes("utf-8"), 0, text.length());
return convertToHex(md.digest());
}
private String convertToHex(byte[] data)
{
StringBuilder buf = new StringBuilder();
int len = data.length;
for (int i = 0; i < len; i++)
{
int halfByte = (data[i] >>> 4) & 0xF;
int twoHalfs = 0;
do
{
if (0 <= halfByte && halfByte <= 9)
{
buf.append((char) ('0' + halfByte));
}
else
{
buf.append((char) ('a' + halfByte - 10));
}
halfByte = data[i] & 0xF;
} while (twoHalfs++ < 1);
}
return buf.toString();
}
}
And this, is the communication with the server with the sent and received messages:
PM SENT (1132418216): <stream:stream to="chat.facebook.com" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0">
PM RCV (1132418216): <?xml version="1.0"?><stream:stream id="C62D0F43" from="chat.facebook.com" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0" xml:lang="en"><stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>X-FACEBOOK-PLATFORM</mechanism><mechanism>DIGEST-MD5</mechanism></mechanisms></stream:features>
PM SENT (1132418216): <auth mechanism="X-FACEBOOK-PLATFORM" xmlns="urn:ietf:params:xml:ns:xmpp-sasl"></auth>
PM RCV (1132418216): <challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">dmVyc2lvbj0xJm1ldGhvZD1hdXRoLnhtcHBfbG9naW4mbm9uY2U9NzFGNkQ3Rjc5QkIyREJCQ0YxQTkwMzA0QTg3OTlBMzM=</challenge>
PM SENT (1132418216): <response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">YXBpX2tleT0zMWYzYjg1ZjBjODYwNjQ3NThiZTZhOTQyNjVjZmNjMCZjYWxsX2lkPTEzMDA0NTYxMzUmbWV0aG9kPWF1dGgueG1wcF9sb2dpbiZub25jZT03MUY2RDdGNzlCQjJEQkJDRjFBOTAzMDRBODc5OUEzMyZzZXNzaW9uX2tleT0yNjUzMTg4ODNkYWJhOGRlOTRiYTk4ZDYtMTAwMDAwNTAyNjc2Nzc4JnY9MS4wJnNpZz04RkRDRjRGRTgzMENGOEQ3QjgwNjdERUQyOEE2RERFQw==</response>
PM RCV (1132418216): <failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>
As read in the developers Facebook forum, it is needed to disable the "Disable Deprecated Auth Methods" setting from the Facebook settings page of your app. But, even doing that, I can't login. And the session key is the second part of the OAuth token in the form AAA|BBB|CCC, I mean, BBB.
Finally, thanks to the no.good.at.coding code and the suggestion of harism, I've been able to connect to the Facebook chat. This code is the Mechanism for the Asmack library (the Smack port for Android). For the Smack library is necessary to use the no.good.at.coding mechanism.
SASLXFacebookPlatformMechanism.java:
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import org.apache.harmony.javax.security.auth.callback.CallbackHandler;
import org.apache.harmony.javax.security.sasl.Sasl;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.sasl.SASLMechanism;
import org.jivesoftware.smack.util.Base64;
public class SASLXFacebookPlatformMechanism extends SASLMechanism
{
private static final String NAME = "X-FACEBOOK-PLATFORM";
private String apiKey = "";
private String applicationSecret = "";
private String sessionKey = "";
/**
* Constructor.
*/
public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication)
{
super(saslAuthentication);
}
#Override
protected void authenticate() throws IOException, XMPPException
{
getSASLAuthentication().send(new AuthMechanism(NAME, ""));
}
#Override
public void authenticate(String apiKeyAndSessionKey, String host,
String applicationSecret) throws IOException, XMPPException
{
if (apiKeyAndSessionKey == null || applicationSecret == null)
{
throw new IllegalArgumentException("Invalid parameters");
}
String[] keyArray = apiKeyAndSessionKey.split("\\|", 2);
if (keyArray.length < 2)
{
throw new IllegalArgumentException(
"API key or session key is not present");
}
this.apiKey = keyArray[0];
this.applicationSecret = applicationSecret;
this.sessionKey = keyArray[1];
this.authenticationId = sessionKey;
this.password = applicationSecret;
this.hostname = host;
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
this.sc =
Sasl.createSaslClient(mechanisms, null, "xmpp", host, props,
this);
authenticate();
}
#Override
public void authenticate(String username, String host, CallbackHandler cbh)
throws IOException, XMPPException
{
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
this.sc =
Sasl.createSaslClient(mechanisms, null, "xmpp", host, props,
cbh);
authenticate();
}
#Override
protected String getName()
{
return NAME;
}
#Override
public void challengeReceived(String challenge) throws IOException
{
byte[] response = null;
if (challenge != null)
{
String decodedChallenge = new String(Base64.decode(challenge));
Map<String, String> parameters = getQueryMap(decodedChallenge);
String version = "1.0";
String nonce = parameters.get("nonce");
String method = parameters.get("method");
long callId = new GregorianCalendar().getTimeInMillis();
String sig =
"api_key=" + apiKey + "call_id=" + callId + "method="
+ method + "nonce=" + nonce + "session_key="
+ sessionKey + "v=" + version + applicationSecret;
try
{
sig = md5(sig);
} catch (NoSuchAlgorithmException e)
{
throw new IllegalStateException(e);
}
String composedResponse =
"api_key=" + URLEncoder.encode(apiKey, "utf-8")
+ "&call_id=" + callId + "&method="
+ URLEncoder.encode(method, "utf-8") + "&nonce="
+ URLEncoder.encode(nonce, "utf-8")
+ "&session_key="
+ URLEncoder.encode(sessionKey, "utf-8") + "&v="
+ URLEncoder.encode(version, "utf-8") + "&sig="
+ URLEncoder.encode(sig, "utf-8");
response = composedResponse.getBytes("utf-8");
}
String authenticationText = "";
if (response != null)
{
authenticationText =
Base64.encodeBytes(response, Base64.DONT_BREAK_LINES);
}
// Send the authentication to the server
getSASLAuthentication().send(new Response(authenticationText));
}
private Map<String, String> getQueryMap(String query)
{
Map<String, String> map = new HashMap<String, String>();
String[] params = query.split("\\&");
for (String param : params)
{
String[] fields = param.split("=", 2);
map.put(fields[0], (fields.length > 1 ? fields[1] : null));
}
return map;
}
private String md5(String text) throws NoSuchAlgorithmException,
UnsupportedEncodingException
{
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(text.getBytes("utf-8"), 0, text.length());
return convertToHex(md.digest());
}
private String convertToHex(byte[] data)
{
StringBuilder buf = new StringBuilder();
int len = data.length;
for (int i = 0; i < len; i++)
{
int halfByte = (data[i] >>> 4) & 0xF;
int twoHalfs = 0;
do
{
if (0 <= halfByte && halfByte <= 9)
{
buf.append((char) ('0' + halfByte));
}
else
{
buf.append((char) ('a' + halfByte - 10));
}
halfByte = data[i] & 0xF;
} while (twoHalfs++ < 1);
}
return buf.toString();
}
}
To use it:
ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com", 5222);
config.setSASLAuthenticationEnabled(true);
XMPPConnection xmpp = new XMPPConnection(config);
try
{
SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM", SASLXFacebookPlatformMechanism.class);
SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);
xmpp.connect();
xmpp.login(apiKey + "|" + sessionKey, sessionSecret, "Application");
} catch (XMPPException e)
{
xmpp.disconnect();
e.printStackTrace();
}
apiKey is the API key given in the application settings page in Facebook. sessionKey is the second part of the access token. If the token is in this form, AAA|BBB|CCC, the BBB is the session key. sessionSecret is obtained using the old REST API with the method auth.promoteSession. To use it, it's needed to make a Http get to this url:
https://api.facebook.com/method/auth.promoteSession?access_token=yourAccessToken
Despite of the Facebook Chat documentation says that it's needed to use your application secret key, only when I used the key that returned that REST method I was able to make it works. To make that method works, you have to disable the Disable Deprecated Auth Methods option in the Advance tab in your application settings.
I'd used this about 6 months ago with Smack (not asmack) so I'm not sure how it'll hold up now but here goes, hope it helps!
I found an implementation of Facebook's X-FACEBOOK-PLATFORM authentication mechanism on the Ignite Realtime Smack forum where someone got it from the fbgc project. You'll find the a ZIP with the SASLXFacebookPlatformMechanism.java source in the answer I linked to. You can use it as follows:
public void login() throws XMPPException
{
SASLAuthentication.registerSASLMechanism(SASLXFacebookPlatformMechanism.NAME,
SASLXFacebookPlatformMechanism.class);
SASLAuthentication.supportSASLMechanism(SASLXFacebookPlatformMechanism.NAME, 0);
ConnectionConfiguration connConfig = new ConnectionConfiguration(host, port);
XMPPConnection connection = new XMPPConnection(connConfig);
connection.connect();
log.info("XMPP client connected");
connection.login(Utils.FB_APP_ID + "|" + this.user.sessionId, Utils.FB_APP_SECRET, "app_name");
log.info("XMPP client logged in");
}
I was doing this on the server without an SDK. I don't remember the details (and the Facebook documentation isn't very good) but from what I can tell from my code, after getting the user to authorize the app, I get a callback request from Facebook with a code parameter. I open a URLConnection to https://graph.facebook.com/oauth/access_token?client_id=<app_id>&redirect_uri=http://myserver/context/path/&client_secret=<app_secret>&code=<code>. The response should be the access token where the session id is the part after the | - something of the form XXX|<sessionId>.
Here's code I've been using successfully for authentication. Maybe this helps even though this is not related to Smack in any way. You can get sessionKey from access token received from FB, and for getting sessionSecret I've been using oldish REST API;
http://developers.facebook.com/docs/reference/rest/auth.promoteSession/
private final void processChallenge(XmlPullParser parser, Writer writer,
String sessionKey, String sessionSecret) throws IOException,
NoSuchAlgorithmException, XmlPullParserException {
parser.require(XmlPullParser.START_TAG, null, "challenge");
String challenge = new String(Base64.decode(parser.nextText(),
Base64.DEFAULT));
String params[] = challenge.split("&");
HashMap<String, String> paramMap = new HashMap<String, String>();
for (int i = 0; i < params.length; ++i) {
String p[] = params[i].split("=");
p[0] = URLDecoder.decode(p[0]);
p[1] = URLDecoder.decode(p[1]);
paramMap.put(p[0], p[1]);
}
String api_key = "YOUR_API_KEY";
String call_id = "" + System.currentTimeMillis();
String method = paramMap.get("method");
String nonce = paramMap.get("nonce");
String v = "1.0";
StringBuffer sigBuffer = new StringBuffer();
sigBuffer.append("api_key=" + api_key);
sigBuffer.append("call_id=" + call_id);
sigBuffer.append("method=" + method);
sigBuffer.append("nonce=" + nonce);
sigBuffer.append("session_key=" + sessionKey);
sigBuffer.append("v=" + v);
sigBuffer.append(sessionSecret);
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(sigBuffer.toString().getBytes());
byte[] digest = md.digest();
StringBuffer sig = new StringBuffer();
for (int i = 0; i < digest.length; ++i) {
sig.append(Integer.toHexString(0xFF & digest[i]));
}
StringBuffer response = new StringBuffer();
response.append("api_key=" + URLEncoder.encode(api_key));
response.append("&call_id=" + URLEncoder.encode(call_id));
response.append("&method=" + URLEncoder.encode(method));
response.append("&nonce=" + URLEncoder.encode(nonce));
response.append("&session_key=" + URLEncoder.encode(sessionKey));
response.append("&v=" + URLEncoder.encode(v));
response.append("&sig=" + URLEncoder.encode(sig.toString()));
StringBuilder out = new StringBuilder();
out.append("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>");
out.append(Base64.encodeToString(response.toString().getBytes(),
Base64.NO_WRAP));
out.append("</response>");
writer.write(out.toString());
writer.flush();
}
I'm sorry to make new answer but I had to include the new code #YShinkarev sorry for being late
By modifying #Adrian answer to make challengeReceived we can use APIKey and accessToken all I modified was the composedResponse
#Override
public void challengeReceived(String challenge) throws IOException {
byte[] response = null;
if (challenge != null) {
String decodedChallenge = new String(Base64.decode(challenge));
Map<String, String> parameters = getQueryMap(decodedChallenge);
String version = "1.0";
String nonce = parameters.get("nonce");
String method = parameters.get("method");
long callId = new GregorianCalendar().getTimeInMillis();
String composedResponse = "api_key="
+ URLEncoder.encode(apiKey, "utf-8") + "&call_id=" + callId
+ "&method=" + URLEncoder.encode(method, "utf-8")
+ "&nonce=" + URLEncoder.encode(nonce, "utf-8")
+ "&access_token="
+ URLEncoder.encode(access_token, "utf-8") + "&v="
+ URLEncoder.encode(version, "utf-8");
response = composedResponse.getBytes("utf-8");
}
String authenticationText = "";
if (response != null) {
authenticationText = Base64.encodeBytes(response,
Base64.DONT_BREAK_LINES);
}
// Send the authentication to the server
getSASLAuthentication().send(new Response(authenticationText));
}
What do you want to do?
If you just want to login on FB chat, you connect to FB just like any other XMPP server.
I would look at and use "Authenticating with Username/Password" from Chat API, wich is supported by Smack. Unless I would like to write an FaceBook-application. Then I would try to login in with "Authenticating with Facebook Platform".
So, just use Smack to connect to FB chat as you would do with your ordinary Jabber client.
For the username, use your Facebook username. (see http://www.facebook.com/username/ )
For the domain, use: chat.facebook.com
For the password, use your Facebook password
Turn off SSL and TSL
Set connect port to: 5222 (which is the default for XMPP)
Set connect server to chat.facebook.com

LinkedIn integration - Establish a requestToken

I'm developing (trying for now) portlet that will be integrated with LinkedIn.
Following the documentation about it:
http://developer.linkedin.com/docs/DOC-1008 -->
The first step to authorizing a LinkedIn member is requesting a requestToken. This request is done with an HTTP POST.
For the requestToken step, the following components should be present in your string to sign:
* HTTP Method (POST)
* Request URI (https://api.linkedin.com/uas/oauth/requestToken)
* oauth_callback
* oauth_consumer_key
* oauth_nonce
* oauth_signature_method
* oauth_timestamp
* oauth_version
I have already API(it's oauth_consumer_key) key and i need to generate specific URL string.
Have next java code for this URL and HTTP connection:
private void processAuthentication() {
Calendar cal = Calendar.getInstance();
Long ms = cal.getTimeInMillis();
Long timestamp = ms / 1000;
Random r = new Random();
Long nonce = r.nextLong();
String prefixUrl = "https://api.linkedin.com/uas/oauth/requestToken";
String oauthCallback = "oauth_callback=http://localhost/";
String oauthConsumerKey =
"&oauth_consumer_key=my_consumer_key";
String oauthNonce = "&oauth_nonce=" + nonce.toString();
String oauthSignatureMethod = "&oauth_signature_method=HMAC-SHA1";
String oauthTimestamp = "&oauth_timestamp=" + timestamp.toString();
String oauthVersion = "&oauth_version=1.0";
String mainUrl =
oauthCallback + oauthConsumerKey + oauthNonce + oauthSignatureMethod
+ oauthTimestamp + oauthVersion;
try {
prefixUrl =
URLEncoder.encode(prefixUrl, "UTF-8") + "&"
+ URLEncoder.encode(mainUrl, "UTF-8");
URL url = new URL(prefixUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
String msg = connection.getResponseMessage();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
The question is next,for those, who had faced this problem:
How should really look URL string for connection and how response is received?
For URL, it's interested the example of URL, you generated.
And for response interested, method to get it.
As i understand, after HTTP connection been established,that response is:
connection.getResponseMessage();
#sergionni I found answer to your Question from linkedin-developer
As you know
The first step to authorizing a Linked-In member is requesting a requestToken. This request is done with an HTTP POST.
Your base string should end up looking something like this if you're using a callback:
POST&https%3A%2F%2Fapi.linkedin.com%2Fuas%2Foauth%2FrequestToken
&oauth_callback%3Dhttp%253A%252F%252Flocalhost%252Foauth_callback%26o
auth_consumer_key%3DABCDEFGHIJKLMNOPQRSTUVWXYZ%26
oauth_nonce%3DoqwgSYFUD87MHmJJDv7bQqOF2EPnVus7Wkqj5duNByU%26
oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1259178158%26
oauth_version%3D1.0
You then sign this base string with your consumer_secret, computing a signature. In this case, if your secret was 1234567890, the signature would be TLQXuUzM7omwDbtXimn6bLDvfF8=.
Now you take the signature you generated, along with oauth_nonce, oauth_callback, oauth_signature_method, oauth_timestamp, oauth_consumer_key, and oauth_version and create an HTTP Authorization header. For this request, that HTTP header would look like:
Authorization: OAuth
oauth_nonce="oqwgSYFUD87MHmJJDv7bQqOF2EPnVus7Wkqj5duNByU",
oauth_callback="http%3A%2F%2Flocalhost%2Foauth_callback",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1259178158",
oauth_consumer_key="ABCDEFGHIJKLMNOPQRSTUVWXYZ",
oauth_signature="TLQXuUzM7omwDbtXimn6bLDvfF8=",
oauth_version="1.0"
Please note, that the HTTP header is a single header -- not an HTTP header for each component. You can optionally supply a realm="http://api.linkedin.com".
As a response to your request for a requestToken, your requestToken will be in the "oauth_token" response field, a validation that we acknowledged your callback with the "oauth_callback_confirmed" field, an oauth_token_secret, and a oauth_expires_in, and a few other values.
(here us Your answaer) response would look like:
oauth_token=94ab03c4-ae2c-45e4-8732-0e6c4899db63
&oauth_token_secret=be6ccb24-bf0a-4ea8-a4b1-0a70508e452b
&oauth_callback_confirmed=true&oauth_expires_in=599
You might try out the OAuth libraries to handle the connection: http://code.google.com/p/oauth/
I created a plugin for Play Framework to easily integrated with LinkedIn's OAuth: geeks.aretotally.in/projects/play-framework-linkedin-module. Hopefully it can help. You should def check out Play, very very cool Java framework.
portlet body:
public class LinkedInPortlet extends GenericPortlet {
public static final String PAGE_PIN = "pin";
public static final String PAGE_EDIT = "edit";
public static final String PAGE_PROFILE = "profile";
public static final String PAGE_CONNECTIONS = "connections";
public static final String FORM_LINKEDIN_PREFERENCES = "preferencesLinkedInForm";
public static final String PAGE_VIEW_MY_PROFILE = "/WEB-INF/portlets/linkedin/myProfile.jsp";
public static final String PAGE_VIEW_MY_CONNECTIONS =
"/WEB-INF/portlets/linkedin/myConnections.jsp";
public static final String PAGE_PREFERENCES = "/WEB-INF/portlets/linkedin/edit.jsp";
public void doView(RenderRequest request, RenderResponse response) throws PortletException,
IOException {
String view = PAGE_VIEW_MY_PROFILE;
String page =
(String) request.getPortletSession().getAttribute(
"page_" + getPortletIdentifier(request), PortletSession.PORTLET_SCOPE);
String accessTokenToken =
getStringConfiguration(request, LinkedInPreferencesForm.PARAM_ACCESS_TOKEN_TOKEN);
String accessTokenSecret =
getStringConfiguration(request, LinkedInPreferencesForm.PARAM_ACCESS_TOKEN_SECRET);
LinkedInContact profile = new LinkedInContact();
List<LinkedInContact> contacts = new ArrayList<LinkedInContact>();
if (PAGE_PIN.equals(page)) {
view = PAGE_PREFERENCES;
} else if (PAGE_EDIT.equals(page)) {
view = PAGE_PREFERENCES;
} else if (PAGE_CONNECTIONS.equals(page)) {
try {
contacts =
ServiceResolver.getResolver().getLinkedInService().getConnections(
accessTokenToken, accessTokenSecret);
} catch (ServiceException se) {
view = PAGE_PREFERENCES;
handleException(request, se);
}
view = PAGE_VIEW_MY_CONNECTIONS;
} else {
try {
profile =
ServiceResolver.getResolver().getLinkedInService().getProfile(
accessTokenToken, accessTokenSecret);
} catch (ServiceException se) {
view = PAGE_PREFERENCES;
handleException(request, se);
}
view = PAGE_VIEW_MY_PROFILE;
}
request.setAttribute("profile", profile);
request.setAttribute("contacts", contacts);
response.setContentType(request.getResponseContentType());
PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(view);
rd.include(request, response);
}
public void processAction(ActionRequest request, ActionResponse response)
throws PortletException, IOException {
String action;
action = (String) request.getParameter("action");
String page = request.getParameter("page");
if (page == null) {
page = PAGE_PROFILE;
} else if ("auth".equals(action)) {
request.getPortletSession().setAttribute(
"requestToken_" + getPortletIdentifier(request),
ServiceResolver.getResolver().getLinkedInService().getRequestToken(),
PortletSession.APPLICATION_SCOPE);
LinkedInPreferencesForm form = new LinkedInPreferencesForm(request);
request.getPortletSession().setAttribute(
FORM_LINKEDIN_PREFERENCES + getPortletIdentifier(request), form,
PortletSession.APPLICATION_SCOPE);
response.setPortletMode(PortletMode.EDIT);
} else if ("save".equals(action)) {
try {
try {
savePreferences(request, response);
} catch (ServiceException e) {
handleException(request, e);
}
} catch (PortletModeException e) {
handleException(request, e);
}
} else if ("myProfile".equals(action)) {
page = PAGE_PROFILE;
} else if ("myConnections".equals(action)) {
page = PAGE_CONNECTIONS;
}
if (page != null) {
request.getPortletSession().setAttribute("page_" + getPortletIdentifier(request), page,
PortletSession.PORTLET_SCOPE);
}
}
private void savePreferences(ActionRequest request, ActionResponse response)
throws PortletModeException, ServiceException {
LinkedInPreferencesForm form = new LinkedInPreferencesForm(request);
if (validateForm(request, form)) {
LinkedInRequestToken requestToken =
(LinkedInRequestToken) request.getPortletSession().getAttribute(
"requestToken_" + getPortletIdentifier(request),
PortletSession.APPLICATION_SCOPE);
String pin = request.getParameter("pinCode");
LinkedInAccessToken accessToken;
try {
accessToken =
ServiceResolver.getResolver().getLinkedInService().getAccessToken(
requestToken, pin);
} catch (LinkedInOAuthServiceException ase) {
response.setPortletMode(PortletMode.EDIT);
throw new ServiceException("linkedin.authentication.failed");
}
String tokenToken = requestToken.getToken();
String secret = requestToken.getTokenSecret();
String tokenURL = requestToken.getAuthorizationUrl();
Properties configuration = new Properties();
configuration.setProperty(LinkedInPreferencesForm.PARAM_PIN, form.getPin());
configuration
.setProperty(LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_TOKEN, tokenToken);
configuration.setProperty(LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_SECRET, secret);
configuration.setProperty(LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_URL, tokenURL);
configuration.setProperty(LinkedInPreferencesForm.PARAM_ACCESS_TOKEN_TOKEN, accessToken
.getToken());
configuration.setProperty(LinkedInPreferencesForm.PARAM_ACCESS_TOKEN_SECRET,
accessToken.getTokenSecret());
ServiceResolver.getResolver().getPortalService().savePortletConfiguration(request,
configuration);
resetSessionForm(request, FORM_LINKEDIN_PREFERENCES);
response.setPortletMode(PortletMode.VIEW);
} else {
// store in session
request.getPortletSession().setAttribute(
FORM_LINKEDIN_PREFERENCES + getPortletIdentifier(request), form,
PortletSession.APPLICATION_SCOPE);
response.setPortletMode(PortletMode.EDIT);
logger.debug(FORM_LINKEDIN_PREFERENCES + " is in edit mode");
}
}
#Override
protected void addConfiguration(MessageSource messageSource, Locale locale,
Map<String, String> result) {
result.put(LinkedInPreferencesForm.PARAM_PIN, messageSource.getMessage(
"linkedIn.preferences.pin", null, locale));
result.put(LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_TOKEN, messageSource.getMessage(
"linkedIn.preferences.requestTokenToken", null, locale));
result.put(LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_SECRET, messageSource.getMessage(
"linkedIn.preferences.requestTokenSecret", null, locale));
result.put(LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_URL, messageSource.getMessage(
"linkedIn.preferences.requestTokenURL", null, locale));
result.put(LinkedInPreferencesForm.PARAM_ACCESS_TOKEN_TOKEN, messageSource.getMessage(
"linkedIn.preferences.accessToken", null, locale));
result.put(LinkedInPreferencesForm.PARAM_ACCESS_TOKEN_SECRET, messageSource.getMessage(
"linkedIn.preferences.accessTokenSecret", null, locale));
}
#Override
protected void addPreference(MessageSource messageSource, Locale locale,
Map<String, String> result) {
}
#Override
public String getAsyncTitle(RenderRequest request) {
return this.getTitle(request);
}
protected boolean validateForm(ActionRequest request, LinkedInPreferencesForm form) {
return form.validate();
}
protected String myEdit(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
LinkedInPreferencesForm form = new LinkedInPreferencesForm();
form.setPin(getStringConfiguration(request, LinkedInPreferencesForm.PARAM_PIN));
form.setRequestTokenToken(getStringConfiguration(request,
LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_TOKEN));
form.setRequestTokenSecret(getStringConfiguration(request,
LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_SECRET));
form.setRequestTokenURL(getStringConfiguration(request,
LinkedInPreferencesForm.PARAM_REQUEST_TOKEN_URL));
registerSessionForm(request, FORM_LINKEDIN_PREFERENCES, form);
LinkedInRequestToken requestToken;
requestToken =
(LinkedInRequestToken) request.getPortletSession().getAttribute(
"requestToken_" + getPortletIdentifier(request),
PortletSession.APPLICATION_SCOPE);
if (requestToken == null) {
requestToken =
new LinkedInRequestToken(form.getRequestTokenToken(), form
.getRequestTokenSecret());
requestToken.setAuthorizationUrl(form.getRequestTokenURL());
}
request.setAttribute("requestToken", requestToken);
return PAGE_PREFERENCES;
}
}

Categories