SMACK API 带内注册失败并出现禁止错误

Posted

技术标签:

【中文标题】SMACK API 带内注册失败并出现禁止错误【英文标题】:SMACK API In Band registration fails with forbidden error 【发布时间】:2015-12-19 00:32:41 【问题描述】:

我正在使用 SMACK API 的 AccountManager 类,但未能成功创建新帐户。支持AccountCreation() 返回真。 createAccount 方法失败并出现以下错误。

D/SMACK: SENT (0): <iq to='xmpp.jp' id='e740L-48' type='set'><query     xmlns='jabber:iq:register'><username>MY_NEW_USER</username><password>**********************</password></query></iq>
D/SMACK: RECV (0): <iq from='xmpp.jp' id='e740L-48' type='error'><query xmlns='jabber:iq:register'><username>MY_NEW_USER</username><password>*****************</password></query><error code='403' type='auth'><forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>
W/System.err: org.jivesoftware.smack.XMPPException$XMPPErrorException: XMPPError: forbidden - auth
W/System.err:     at org.jivesoftware.smack.PacketCollector.nextResultOrThrow(PacketCollector.java:232)
W/System.err:     at org.jivesoftware.smack.PacketCollector.nextResultOrThrow(PacketCollector.java:213)
W/System.err:     at org.jivesoftware.smackx.iqregister.AccountManager.createAccount(AccountManager.java:272)
W/System.err:     at org.jivesoftware.smackx.iqregister.AccountManager.createAccount(AccountManager.java:244)
..
D/SMACK: SENT (0): <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='SCRAM-SHA-1'>*****************************************</auth>
D/SMACK: RECV (0): <failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><not-authorized/></failure>

更新:此处添加代码 API v4.1.5

private void initialiseConnection() 
    Log.d("xmpp", "Initialising connection");
    XMPPTCPConnectionConfiguration.Builder config = XMPPTCPConnectionConfiguration.builder();
    config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
    config.setServiceName(getServer());
    config.setHost(getServer());
    config.setPort(getPort());
    config.setDebuggerEnabled(true);
    config.setSendPresence(true);


    XMPPTCPConnection.setUseStreamManagementResumptionDefault(true);
    XMPPTCPConnection.setUseStreamManagementDefault(true);
    connection = new XMPPTCPConnection(config.build());

    connection.addConnectionListener(new XMPPConnectionStateHandler(this));
    connection.addConnectionListener(new XMPPAccountLoginHandler(this));
    connection.addConnectionListener(new XMPPOfflineMessageHandler(this));
    connection.addConnectionListener(new XMPPPingMessageHandler(this));
    connection.addConnectionListener(new XMPPReconnectionHandler(this));
    connection.addConnectionListener(new XMPPPresenceHandler(this));
    connection.addConnectionListener(new XMPPDeliveryReceiptHandler(this));


public void connect(final String caller) 
    if (ConnectionManagerHelper.hasDataConnection(context))
        Log.d(TAG, "Data connection fine");
     else 
        Log.d(TAG, "Data connection not avaiable");
    
    AsyncTask<Void, Void, Boolean> connectionThread = new AsyncTask<Void, Void, Boolean>() 
        @Override
        protected synchronized Boolean doInBackground(Void... arg0) 
            if (connection.isConnected()) return false;
            isconnecting = true;
            Log.d("Connect() Function", caller + "=>connecting....");

            try 
                connection.connect();
                connected = true;
                notifyConnectionEstablishedEvent();
             catch (IOException e) 
                Log.e(TAG, "(" + caller + ")" + " IOException: " + e.getMessage());
                notifyConnectionFailureEvent();
             catch (final SmackException e) 
                Log.e(TAG, "(" + caller + ")" + " SMACKException: " + e.getMessage());
                notifyConnectionFailureEvent();
             catch (final XMPPException e) 
                Log.e(TAG, "(" + caller + ")" + " XMPPException: " + e.getMessage());
                notifyConnectionFailureEvent();
            
            return isconnecting = false;
        
    ;
    connectionThread.execute();


public void login() 
    try 
        connection.addAsyncStanzaListener(new StanzaListener() 
            @Override
            public void processPacket(Stanza packet) throws NotConnectedException 
                Log.d(TAG, packet.toXML().toString());
                notifyMessageStatusReceivedEvent(packet);
            
        , new StanzaFilter() 
            @Override
            public boolean accept(Stanza stanza) 
                return true;
            
        );
        Log.d(TAG, "Attempting to login as " + loginUser);
        connection.login(loginUser, passwordUser);
        notifyConnectionConnectedEvent();
     catch (SmackException.AlreadyLoggedInException e)
        Log.d(TAG, "Already logged on to chat server");
     catch (XMPPException | SmackException | IOException e) 
        e.printStackTrace();
        //if first login failed, try to create an account and then login
        Log.d(TAG, "Login failed. Trying to create a new account.");
        register();
    


public void register()
    Log.d(TAG, "Attempting to register");
    try 
        AccountManager accountManager = AccountManager.getInstance(connection);
        if (accountManager.supportsAccountCreation())
            Log.d(TAG, "Server supports remote registration");
            accountManager.sensitiveOperationOverInsecureConnection(true);
            Log.d(TAG, "Sending registration request");
            HashMap<String, String> attributes = new HashMap<>();
            attributes.put("email", "test@gmail.com");
            accountManager.createAccount(loginUser, passwordUser, attributes);
         else 
            Log.w(TAG, "Server does not support remote registrations");
        
     catch (XMPPException | SmackException e) 
        e.printStackTrace();
    

我已经花了 3 天时间进行谷歌搜索和 *** 搜索。 有人已经看到并解决了这个问题吗?

【问题讨论】:

最有可能的问题是您在创建帐户时没有提供足够的信息。请出示您的相关代码。 @Flow,我在问题中添加了代码块。感谢您的帮助 @Flow 我已经编辑了问题并添加了相关代码。还有什么你需要了解的。 @Flow,在您发表评论后,我花了一些时间查看配置,发现缺少资源定义。我添加了资源,现在我不再收到禁止错误。相反,我现在收到了错误的请求 @GorillaCoder 我在注册新用户时也遇到此错误,如果您有任何解决方案,请提供该解决方案。 【参考方案1】:

您必须为注册新用户设置访问规则。我在这里附上了完整的访问规则。您可以通过在访问规则中单击 raw 来添加它。

[access,announce,[allow,[acl,admin]],
 access,c2s,[deny,[acl,blocked],allow,[all]],
 access,c2s_shaper,[none,[acl,admin],normal,[all]],
 access,configure,[allow,[acl,admin]],
 access,local,[allow,[acl,local]],
 access,max_user_offline_messages,[5000,[acl,admin],100,[all]],
 access,max_user_sessions,[10,[all]],
 access,mod_register,[access_from,register_from,access,register],
 access,register,[allow,[acl,local]],
 access,muc_create,[allow,[acl,local]],
 access,pubsub_createnode,[allow,[acl,local]],
 access,register,[allow,[all]],
 access,register_from,[allow,[all]],
 access,s2s_shaper,[fast,[all]],
 access,trusted_network,[allow,[acl,loopback]]]

【讨论】:

【参考方案2】:

下面的代码对我有用,

                AccountManager accountManager = AccountManager.getInstance(connection);
                try 
                    if (accountManager.supportsAccountCreation()) 
                        accountManager.sensitiveOperationOverInsecureConnection(true);
                        accountManager.createAccount("name", "password");

                    
                 catch (SmackException.NoResponseException e) 
                    e.printStackTrace();
                 catch (XMPPException.XMPPErrorException e) 
                    e.printStackTrace();
                 catch (SmackException.NotConnectedException e) 
                    e.printStackTrace();
                

【讨论】:

以上是关于SMACK API 带内注册失败并出现禁止错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 Android 上的 Smack API 获取在服务器上注册并具有在线/离线状态的所有用户的列表

使用 Smack 4.1.3 注册用户

SIP/XMPP:ejabberd 和 mod_register:注册:禁止

GCM 注册失败,出现 1003 错误

eyeBeam1.5网络电话注册码激活后 注册SIP账号设定失败:出现注册错误403-Forbidden 怎么解决知道的告诉谢

XMPP Smack 4.1.0 检查用户是不是已经注册