android - Gtalk XMPP SASL 身份验证使用机制 X-OAUTH2 失败?

标签 android xmpp google-oauth

我在我的聊天应用程序中使用 GoogleTalk XMPP。无法使用用户名和 AuthToken 与 Google 身份验证 创建 XMPP 连接。

现在我正在使用 GoogleAuth2 进行身份验证。我尝试使用 access_token 和电子邮件进行身份验证。通过使用 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("<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" + 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("</auth>");

    // 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("<auth mechanism=\"").append(name);
        stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
        if (authenticationText != null
                && authenticationText.trim().length() > 0) {
            stanza.append(authenticationText);
        }
        stanza.append("</auth>");
        return stanza.toString();
    }
}
}

如何使用 SASL 机制验证 Google Auth

最佳答案

这是一个适用于我的版本,使用 OAUTH2 token 。 OAUTH2 范围是 https://www.googleapis.com/auth/googletalk

此代码使用 Smack XMPP 库。

OAuth2认证机制:

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<String, String> props = new HashMap<String, String>();
        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
    }

}

关于android - Gtalk XMPP SASL 身份验证使用机制 X-OAUTH2 失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15517694/

相关文章:

安卓功能测试;将地理位置发送到模拟器

XMPP MUC加入时返回错误码404,但存在

xmpp - 动态更改JID的资源而无需注销

google-api - 从 Google oauth2 API 获取错误 { "error": "invalid_grant", "error_description": "Token has been expired or revoked."}

google-app-engine - 部署时未更新 ClientId - 用户注入(inject) null

node.js - 通过 Cloud Functions 访问 Gmail API

java - 如何在特定的 ViewPager 页面隐藏 View ?请查看详情

android - Windows 8 上的 Firefox 远程调试 "unexpected error"

android - 如何在这个特定的 Android 用例中实现 MQTT?

android - ML Kit文本识别: How to get text based on position in image?