Gtalk XMPP SASL身份validation使用X-OAUTH2机制失败了吗?

我在我的应用程序中使用GoogleTalk XMPP进行聊天。 无法使用用户名和AuthToken与Google authentication创建XMPP连接。

现在我使用GoogleAuth2进行authentication 。 我尝试使用access_token和电子邮件进行身份validation。 通过使用SASLMechanism 。 但我无法连接到xmpp服务器,它给出了这样的错误,因为SASL authentication failed using mechanism X-OAUTH2

 ConnectionConfiguration config = new ConnectionConfiguration(server_host, SERVER_PORT, SERVICE_NAME); config.setSASLAuthenticationEnabled(true); m_connection = new XMPPConnection(config); SASLAuthentication.registerSASLMechanism("X-OAUTH2", GoogleConnectSASLMechanism.class); SASLAuthentication.supportSASLMechanism("X-OAUTH2", 0); config.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled); try { m_connection.connect(); } catch (XMPPException e) { e.printStackTrace(); } 

这是我用于SASLMechanism.

 public class GoogleConnectSASLMechanism extends SASLMechanism { public static final String NAME = "X-OAUTH2"; private String username = ""; private String sessionKey = ""; public GoogleConnectSASLMechanism(SASLAuthentication saslAuthentication) { super(saslAuthentication); } @Override protected String getName() { return NAME; } static void enable() { } @Override protected void authenticate() throws IOException, XMPPException { final StringBuilder stanza = new StringBuilder(); byte response[] = null; stanza.append(""); String composedResponse = "\0" + username + "\0" + sessionKey; response = composedResponse.getBytes("UTF-8"); String authenticationText = ""; if (response != null) { authenticationText = Base64.encodeBytes(response, Base64.DONT_BREAK_LINES); } stanza.append(authenticationText); stanza.append(""); // Send the authentication to the server Packet p=new Packet() { @Override public String toXML() { return stanza.toString(); } }; getSASLAuthentication().send(p); } public class Auth2Mechanism extends Packet { String stanza; public Auth2Mechanism(String txt) { stanza = txt; } public String toXML() { return stanza; } } /** * Initiating SASL authentication by select a mechanism. */ public class AuthMechanism extends Packet { final private String name; final private String authenticationText; public AuthMechanism(String name, String authenticationText) { if (name == null) { throw new NullPointerException( "SASL mechanism name shouldn't be null."); } this.name = name; this.authenticationText = authenticationText; } public String toXML() { StringBuilder stanza = new StringBuilder(); stanza.append(""); if (authenticationText != null && authenticationText.trim().length() > 0) { stanza.append(authenticationText); } stanza.append(""); return stanza.toString(); } } } 

如何使用SASL机制validationGoogle Auth

这是一个使用OAUTH2令牌的版本。 OAUTH2范围是https://www.googleapis.com/auth/googletalk

此代码使用Smack XMPP库。

OAuth2身份validation机制:

 import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; import 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 SALSGTalkOauthMechanism extends SASLMechanism { private static final Logger log = Logger.getLogger(SALSGTalkOauthMechanism.class.getName()); public static final String NAME = "X-OAUTH2"; /** * Constructor. */ public SALSGTalkOauthMechanism(SASLAuthentication saslAuthentication) { super(saslAuthentication); log.info("Creating SASL mechanism for GTalk (X-OAUTH2)"); } @Override public void authenticate(String username, String host, String accessToken) throws IOException, XMPPException { this.hostname = host; log.info("Authenticating to host "+host+" with key "+username); String[] mechanisms = { "X-OAUTH2" }; Map props = new HashMap(); this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, this); getSASLAuthentication().send(new AuthMechanism(getName(), Base64.encodeBytes(('\0'+username+'\0'+accessToken).getBytes()))); } @Override protected String getName() { return NAME; } } 

以及使其协同工作的代码:

 import org.jivesoftware.smack.Chat; import org.jivesoftware.smack.ChatManager; import org.jivesoftware.smack.Connection; import org.jivesoftware.smack.ConnectionConfiguration; import org.jivesoftware.smack.SASLAuthentication; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Presence; import revevol.applications.cloudpulse.client.Probe; import revevol.applications.cloudpulse.client.ProbeClient; import revevol.applications.cloudpulse.client.ProbeClientUtils; import com.google.api.client.auth.oauth2.Credential; public class GTalkProbe implements Probe { private static final Logger log = Logger.getLogger(GTalkProbe.class.getName()); public static final String PROBE_GTALK_IDENTIFIER = "gtalkprobe"; @Override public void run(ProbeClient client, Properties properties) throws Exception { log.info("Start running GTalkProbe."); long startTimestamp = new Date().getTime(); Exception exception = null; MessageReboundResult result = new MessageReboundResult(); Connection conn1 = null; try { Credential credential = ProbeClientUtils.getOAuth2Credentials(properties); ConnectionConfiguration config = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com"); config.setCompressionEnabled(true); config.setSASLAuthenticationEnabled(true); conn1 = new XMPPConnection(config); SASLAuthentication.registerSASLMechanism("X-OAUTH2", SALSGTalkOauthMechanism.class); SASLAuthentication.supportSASLMechanism("X-OAUTH2", 0); conn1.connect(); log.info("Logging in"); conn1.login(ProbeClientUtils.getOAuthConsumerId(properties), credential.getAccessToken()); Presence presence = new Presence(Presence.Type.available); presence.setStatus("My status"); conn1.sendPacket(presence); ChatManager chatmanager = conn1.getChatManager(); String destination = "destination@gmail.com"; log.info("Sending chat message to " + destination); String message = "PING : " + UUID.randomUUID().toString(); Chat chat = chatmanager.createChat(destination, new MessageListener(//TODO : here put your stuff)); Message msg = new Message(destination, Message.Type.chat); msg.setBody(message); chat.sendMessage(msg); //Here you are } } 

我在使用XMPP / Openfire服务器聊天应用程序方面做了很多工作。

这是连接/登录服务器的最简单方法 –

 ConnectionConfiguration connConfig = new ConnectionConfiguration("abc.hostname.com",5222); configure(ProviderManager.getInstance()); connection = new XMPPConnection(connConfig); connection.connect(); connection.login(userName, password); 

在登录时获取名单

  roster = connection.getRoster(); roster.setSubscriptionMode(Roster.SubscriptionMode.manual); 

以下是提供程序实例的configure方法

 public void configure(ProviderManager pm) { // MUC Admin pm.addIQProvider("query", "http://jabber.org/protocol/muc#admin",new MUCAdminProvider()); // MUC Owner pm.addIQProvider("query", "http://jabber.org/protocol/muc#owner",new MUCOwnerProvider()); pm.addIQProvider("si", "http://jabber.org/protocol/si",new StreamInitiationProvider()); pm.addIQProvider("query","http://jabber.org/protocol/bytestreams", new org.jivesoftware.smackx.provider.BytestreamsProvider()); pm.addIQProvider("query","http://jabber.org/protocol/disco#items", new DiscoverItemsProvider()); pm.addIQProvider("query","http://jabber.org/protocol/disco#info", new DiscoverInfoProvider()); // Delayed Delivery pm.addExtensionProvider("x", "jabber:x:delay",new DelayInformationProvider()); pm.addIQProvider("vCard", "vcard-temp", new VCardProvider()); // Group Chat Invitations pm.addExtensionProvider("x","jabber:x:conference", new GroupChatInvitation.Provider()); } 

如果您有任何疑问,请告诉我