Is it possible to use AssertionFlowClient and service account to access mailbox of any user in my domain through IMAP. Same as with 2-legged OAuth 1.0.
Here's my code:
X509Certificate2 certificate = new X509Certificate2(...)
AuthorizationServerDescription server = new AuthorizationServerDescription {...};
List<string> scope = new List<string> {
"https://mail.google.com/",
"https://www.googleapis.com/auth/userinfo#email" };
AssertionFlowClient provider = new AssertionFlowClient(server, certificate)
{
ServiceAccountId = SERVICE_ACCOUNT_EMAIL,
Scope = string.Join(" ",scope.ToArray()),
};
IAuthorizationState grantedAccess = AssertionFlowClient.GetState(provider);
accessToken = grantedAccess.AccessToken;
using (Imap client = new Imap())
{
client.ConnectSSL("imap.gmail.com");
client.LoginOAUTH2("user@mydomain.com", accessToken);
...
}
I'm able to retrieve valid accessToken from accounts.google.com server (although AssertionFlowClient/DotNetOpenAuth has a bug and currently I use debugger and watch window to retrieve it).
I'm sure that accessToken is correct, as I can query www.googleapis.com/userinfo/email API endpoint using it - it returns the same value as SERVICE_ACCOUNT_EMAIL.
Gmail's IMAP server returns the following error however:
{"status":"400","schemes":"Bearer","scope":"https://mail.google.com/"}
"Manage API client access" for this service account is configured to "Email (Read/Write/Send) https://mail.google.com/" on cpanel.
AssertionFlowClient/DotNetOpenAuth bug indicates that no-one has ever tried this.
Is it possible at all?
So it seems Google forgot to include this little detail in their documentation:
AssertionFlowClient provider = new AssertionFlowClient(server, certificate)
{
ServiceAccountId = SERVICE_ACCOUNT_EMAIL,
Scope = "https://mail.google.com/",
ServiceAccountUser = "user@mydomain.com", // <- important
};
It also seems that requesting access to multiple scopes (space separated) fails.