Skip to content

Instantly share code, notes, and snippets.

@TomTasche
Last active December 17, 2015 04:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TomTasche/5547823 to your computer and use it in GitHub Desktop.
Save TomTasche/5547823 to your computer and use it in GitHub Desktop.
this gist describes how to 1. get an OAuth token from Android's AccountManager, 2. use this token to connect with GTalk via XMPP. Blog post about it: http://blog.tomtasche.at/2013/05/gtalk-and-oauth-on-android.html
String user = "address@gmail.com";
String password = ""; // fill in the token previously acquired from AccountManager
SmackAndroid smack = SmackAndroid.init(context);
SASLAuthentication.registerSASLMechanism(GTalkOAuthSASLMechanism.NAME,
GTalkOAuthSASLMechanism.class);
SASLAuthentication
.supportSASLMechanism(GTalkOAuthSASLMechanism.NAME, 0);
ConnectionConfiguration configuration = new ConnectionConfiguration(
"talk.google.com", 5222, "gmail.com");
configuration.setSASLAuthenticationEnabled(true);
connection = new XMPPConnection(configuration);
try {
connection.connect();
connection.login(user, password, "joppfm");
} catch (XMPPException e) {
e.printStackTrace();
// an error occured while connecting
}
// taken from: http://stackoverflow.com/a/10712949/198996
// note: you don't have to change anything in this class
public class GTalkOAuthSASLMechanism extends SASLMechanism {
public static final String NAME = "X-GOOGLE-TOKEN";
public GTalkOAuthSASLMechanism(SASLAuthentication saslAuthentication) {
super(saslAuthentication);
}
@Override
protected String getName() {
return NAME;
}
@Override
protected void authenticate() throws IOException, XMPPException {
final StringBuilder stanza = new StringBuilder();
byte response[] = null;
stanza.append("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\""
+ "mechanism=\"X-OAUTH2\"" + "auth:service=\"oauth2\""
+ "xmlns:auth= \"http://www.google.com/talk/protocol/auth\">");
String composedResponse = "\0" + authenticationId + "\0" + password;
response = composedResponse.getBytes("UTF-8");
String authenticationText = "";
if (response != null) {
authenticationText = Base64.encodeBytes(response,
Base64.DONT_BREAK_LINES);
}
stanza.append(authenticationText);
stanza.append("</auth>");
Packet authPacket = new Packet() {
@Override
public String toXML() {
return stanza.toString();
}
};
getSASLAuthentication().send(authPacket);
}
}
private void requestToken() {
AccountManager accountManager = AccountManager.get(this);
// normally you would ask the user which account to use for authentication here
Account account = accountManager.getAccountsByType("com.google")[0];
accountManager.getAuthToken(account,
"oauth2:https://www.googleapis.com/auth/googletalk", null,
this, new OnTokenAcquired(), null);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
requestToken();
} else {
// user aborted authentication
}
}
private class OnTokenAcquired implements AccountManagerCallback<Bundle> {
@Override
public void run(AccountManagerFuture<Bundle> result) {
Bundle bundle = result.getResult();
Intent launch = (Intent) bundle.get(AccountManager.KEY_INTENT);
if (launch != null) {
startActivityForResult(launch, 0);
} else {
// this is the token to use later
String token = bundle
.getString(AccountManager.KEY_AUTHTOKEN);
}
}
}
@TomTasche
Copy link
Author

wtf is wrong with the gist editor? indentation looks fine in the editor, but eventually fucks up. sorry for that!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment