admin管理员组

文章数量:1188009

I use TIdImap4->SendCmd() to send XOAUTH2 token to access my mailbox. I send command:

IdIMAP41->SendCmd("AUTHENTICATE XOAUTH2 " + encodedAuth, OPENARRAY(String, ("AUTHENTICATE XOAUTH2 " + encodedAuth)));

But the server does not respond at all, and does not even throw an error. I don't know if this is due to incorrect coding.

try {
    IdIMAP41->Connect(false);
} catch (const Exception &e) {ShowMessage(L"Wyjątek. Błąd: \n" + e.Message);}
            
// Przygotowanie polecenia AUTH XOAUTH2
String authString = L"adress@domaun\1auth=Bearer " + Token + L"\1\1";
String encodedAuth = TIdEncoderMIME::EncodeString(authString);

String response = IdIMAP41->SendCmd("AUTHENTICATE XOAUTH2 " + encodedAuth, OPENARRAY(String, ("AUTHENTICATE XOAUTH2 " + encodedAuth)));

I tried to get an answer to a query:

String response = IdIMAP41->SendCmd("CAPABILITY", OPENARRAY(String, ("CAPABILITY")));

But I only get the response "OK". I suspect that the commands are incorrect, but I don't know what they should look like.


UPDATE

I tried using the TIdSASLXOAuth2 component:

IdSASLXOAuth21->Username = "email";
IdSASLXOAuth21->Password = Token;

The compiler throws errors like:

[bcc32c Error] Unit1.cpp(159): no member named 'Password' in 'Idsasloauth::TIdSASLXOAuth2'

'[bcc32c Error] Unit1.cpp(158): no member named 'Username' in 'Idsasloauth::TIdSASLXOAuth2'

I use TIdImap4->SendCmd() to send XOAUTH2 token to access my mailbox. I send command:

IdIMAP41->SendCmd("AUTHENTICATE XOAUTH2 " + encodedAuth, OPENARRAY(String, ("AUTHENTICATE XOAUTH2 " + encodedAuth)));

But the server does not respond at all, and does not even throw an error. I don't know if this is due to incorrect coding.

try {
    IdIMAP41->Connect(false);
} catch (const Exception &e) {ShowMessage(L"Wyjątek. Błąd: \n" + e.Message);}
            
// Przygotowanie polecenia AUTH XOAUTH2
String authString = L"adress@domaun\1auth=Bearer " + Token + L"\1\1";
String encodedAuth = TIdEncoderMIME::EncodeString(authString);

String response = IdIMAP41->SendCmd("AUTHENTICATE XOAUTH2 " + encodedAuth, OPENARRAY(String, ("AUTHENTICATE XOAUTH2 " + encodedAuth)));

I tried to get an answer to a query:

String response = IdIMAP41->SendCmd("CAPABILITY", OPENARRAY(String, ("CAPABILITY")));

But I only get the response "OK". I suspect that the commands are incorrect, but I don't know what they should look like.


UPDATE

I tried using the TIdSASLXOAuth2 component:

IdSASLXOAuth21->Username = "email";
IdSASLXOAuth21->Password = Token;

The compiler throws errors like:

[bcc32c Error] Unit1.cpp(159): no member named 'Password' in 'Idsasloauth::TIdSASLXOAuth2'

'[bcc32c Error] Unit1.cpp(158): no member named 'Username' in 'Idsasloauth::TIdSASLXOAuth2'

Share Improve this question edited yesterday Remy Lebeau 595k36 gold badges497 silver badges838 bronze badges asked Jan 24 at 20:34 JacekJacek 631 silver badge10 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

I use TIdImap4->SendCmd to send XOAUTH2 token to access my mailbox.

A recent update to Indy added a few new SASL components for OAuth authentication:

https://www.indyproject.org/2024/10/20/sasl-oauth-support-finally-added-to-master/

once you have a token, you can use it in the new TIdSASLOAuth10A, TIdSASLOAuth2Bearer, and TIdSASLXOAuth2 components. Simply assign the token to the SASL’s Password property, or return it from the SASL’s OnGetAccessToken event.

So, for your example, you can now:

  • create an instance of the TIdSASLXOAuth2 component, and add it to the TIdIMAP4::SASLMechanisms collection.
  • create an instance of the TIdUserPassProvider component, and assign your user email to its Username property and the OAuth token to its Password property.
  • assign the TIdUserPassProvider to the TIdSASLXOAuth2::UserPassProvider property.
  • set the TIdIMAP4::AuthType property to iatSASL.
  • use the TIdIMAP4::Login() method (or set the AAutoLogin parameter of TIdIMAP4::Connect() to true) normally.

If you are not using the latest version of Indy, you should consider upgrading.

I send command: IdIMAP41->SendCmd("AUTHENTICATE XOAUTH2 " + encodedAuth, OPENARRAY(String, ("AUTHENTICATE XOAUTH2 " + encodedAuth))); but the server does not respond at all and does not even throw an error. I don't know if this is due to incorrect coding.

I notice some problems with your code:

  • your authString is missing the user= prefix in front of the email address.

    String authString = L"user=adress@domaun\1auth=Bearer " + Token + L"\1\1";
                          ^^^^^
    
  • you are passing the wrong string value to the AExpectedResponses parameter of TIdIMAP4::SendCmd(). Do not pass it the entire original command, only keywords you are expecting in the response text, like "OK", eg:

    String response = IdIMAP41->SendCmd(L"AUTHENTICATE XOAUTH2 " + encodedAuth, OPENARRAY(String, (L"OK")));
                                                                                                    ^^^^
    

    Or, just leave the AExpectedResponses parameter empty to accept all responses unconditionally:

    // the OPENARRAY() macro does not support empty arrays!
    String response = IdIMAP41->SendCmd(L"AUTHENTICATE XOAUTH2 " + encodedAuth, nullptr, -1);
                                                                                ^^^^^^^^^^^
    

    Either way, if this still doesn't work, then try using the overloaded TIdIMAP4::SendCmd() method that takes an ATag parameter:

    String response = IdIMAP41->SendCmd(IdIMAP41->NewCmdCounter, L"AUTHENTICATE ...", ...);
                                        ^^^^^^^^^^^^^^^^^^^^^^^
    

I tried to get an answer to my query String response = IdIMAP41->SendCmd("CAPABILITY", OPENARRAY(String, ("CAPABILITY"))); But I only get the response 'OK'.

That is what you should be getting. The return value of TIdIMAP4::SendCmd() is the server's response code, not the entire response text. That is stored in the TIdIMAP4::LastCmdResponse->Text property instead.

In any case, you don't need to send a CAPABILITY command manually. TIdIMAP4 has 2 public Capability() methods, and a Capabilities property, for that purpose.

本文标签: oauth 20How to get a response from SendCmd in IndyStack Overflow