Jul 19 2022
10:45 AM
- last edited on
Feb 01 2023
10:22 AM
by
TechCommunityAP
Jul 19 2022
10:45 AM
- last edited on
Feb 01 2023
10:22 AM
by
TechCommunityAP
I am facing an authentication failure issue while trying to connect for both IMAP and POP3 protocols using the Client Credential Grant flow for OAuth2.0
Where, I have been following the steps suggested in "Authenticate an IMAP, POP or SMTP connection using OAuth"
I have been using this github project to fetch the Access Token using Client Credential Grant flow:
MSAL Client Credential Grant using Java
Java Code for IMAP:
public static void connectIMAP(String userEmail, String accessToken){
String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
Properties props= new Properties();
props.put("mail.imap.ssl.enable", "true");
props.put("mail.imap.port", "993");
props.put("mail.imap.auth.mechanisms", "XOAUTH2");
props.put("mail.imap.sasl.mechanisms", "XOAUTH2");
props.put("mail.imap.auth.login.disable", "true");
props.put("mail.imap.auth.plain.disable", "true");
props.setProperty("mail.imap.socketFactory.class", SSL_FACTORY);
props.setProperty("mail.imap.socketFactory.fallback", "false");
props.setProperty("mail.imap.socketFactory.port", "993");
props.setProperty("mail.imap.starttls.enable", "true");
props.put("mail.debug", "true");
props.put("mail.debug.auth", "true");
Session session = Session.getInstance(props);
session.setDebug(true);
try {
final Store store = session.getStore("imap");
store.connect("outlook.office365.com",userEmail, accessToken);
if(store.isConnected()){
System.out.println("Connection Established using imap protocol successfully !");
}
} catch (NoSuchProviderException e) { // session.getStore()
e.printStackTrace();
} catch (MessagingException e) { // store.connect()
e.printStackTrace();
}
}
Java code for POP3:
public static void connectPOP(String email, String accessToken){
Properties properties= new Properties();
properties.put("mail.pop3.port", 995);
properties.put("mail.pop3.forgettopheaders", "true");
properties.put("mail.pop3.auth.mechanisms", "XOAUTH2");
properties.put("mail.pop3.auth.login.disable", "true"); // If true, prevents use of the USER and PASS commands. Default is false.
properties.put("mail.pop3.auth.plain.disable", "true"); // If true, prevents use of the AUTH PLAIN command. Default is false.
properties.put("mail.pop3.auth.xoauth2.disable","false"); // If true, prevents use of the AUTHENTICATE XOAUTH2 command. Hence set it to false
properties.put("mail.pop3.auth.xoauth2.two.line.authentication.format", "true"); // If true, splits authentication command on two lines. Default is false.
properties.put("mail.pop3.connectiontimeout", 15000);
properties.put("mail.pop3.timeout", 15000);
properties.put("mail.debug", "true");
Session session = Session.getInstance(properties);
session.setDebug(true);
try{
Store store = session.getStore("pop3");
store.connect("outlook.office365.com", email, accessToken);
if(store.isConnected()){
System.out.println("Connected with pop3 successfully !");
}
}catch(Exception e){
e.printStackTrace();
}
}
Following are the credentials which I have used while performing the Client Credential Grant flow
Note: I have been using the Default Active Directory, and the default user(Admin) for my Azure account. Is it fine this way ? or does it require a new custom Azure AD and a separate tenant for performing client credential flow |
Below Image contains list of permissions I have applied in my app:
Error Logs:
Spoiler *** IMAP *** DEBUG: JavaMail version 1.5.6
DEBUG: JavaMail version 1.5.6 |
Following is the list of jars I have used as a part of this development:
My Java Code Link(ideone): ClientCredentialGrantAndConnect.java
Please help and let me know if the program is not correct.
Or if any important step seems to be missing.
Thank you.
Jul 29 2022 06:38 AM
Jul 29 2022 07:08 AM
Jul 29 2022 08:42 AM
@jambo Yes, that is the Tenant ID.
Probably you can execute command without Organization ID if you only have one tenant, but it is easier with it, just to be sure.
Jul 29 2022 09:20 AM - edited Jul 29 2022 09:23 AM
Still can't get it to work. When executing the command "Get-ServicePrincipal -Organization <ORGANIZATION_ID> | fl" the serviceId outputted is the same value as OBJECT_ID in the New-ServicePrincipal command, which happens to be equals to Object ID field in the Azure application Overview. Is this correct? From your description, the serviceId value from Get-ServicePrincipal should be different to OBJECT_ID but in my case, they it is the same.
Jul 29 2022 10:38 AM
Jul 29 2022 10:50 AM
Jul 29 2022 11:14 AM
Aug 01 2022 10:31 PM - edited Aug 01 2022 10:39 PM
@borist2 Thank you for pointing out this clue where we need to use OBJECT ID from the Enterprise application view in all the cmdlets i.e. New-ServicePrincipal, Get-ServicePrincipal and Add-MailboxPermission.
It is finally working fine (only for IMAP flow) for me after trying out the same set of steps on a new application, keeping in mind that I have to use OBJECT ID value from Enterprise Application view.
But still there is some issue while trying to connect with this application for POP3 flow.
As per my understanding, following is the list of parameters used while performing Service Principal related queries:
(Please correct me if I am wrong)
Parameters used (and where to find them):
Commands:
Confusions:
@jambo @Anjitha170 @DestryHines Thanks for your suggestions and findings on this issue that I have raised.
However I am still unable to establish a connection through the POP3 protocol, and I want to do it just like we did it for IMAP. Below is the error log for the issue I am facing while trying to connect with POP3. Any help and suggestions will be much appreciated.
*** pop3 ***
DEBUG: JavaMail version 1.5.5
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle]}
DEBUG: Providers Listed By Protocol: {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]}
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
DEBUG: setDebug: JavaMail version 1.5.5
DEBUG: getProvider() returning javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle]
DEBUG POP3: mail.pop3.rsetbeforequit: false
DEBUG POP3: mail.pop3.disabletop: false
DEBUG POP3: mail.pop3.forgettopheaders: true
DEBUG POP3: mail.pop3.cachewriteto: false
DEBUG POP3: mail.pop3.filecache.enable: false
DEBUG POP3: mail.pop3.keepmessagecontent: false
DEBUG POP3: mail.pop3.starttls.enable: true
DEBUG POP3: mail.pop3.starttls.required: false
DEBUG POP3: mail.pop3.apop.enable: false
DEBUG POP3: mail.pop3.disablecapa: false
DEBUG POP3: connecting to host "outlook.office365.com", port 995, isSSL false
+OK The Microsoft Exchange POP3 service is ready. [TQBBAFgAUABSADAAMQAwADEAQwBBAD...==]
CAPA
+OK
TOP
UIDL
SASL PLAIN XOAUTH2
USER
.
DEBUG POP3: authentication command trace suppressed
DEBUG POP3: authentication command failed
QUIT
<EOF>
javax.mail.AuthenticationFailedException: Protocol error. Connection is closed. 10
at com.sun.mail.pop3.POP3Store.protocolConnect(POP3Store.java:209)
at javax.mail.Service.connect(Service.java:366)
at javax.mail.Service.connect(Service.java:246)
at test.ClientCredentialGrant.connectPOP(ClientCredentialGrant.java:242)
at test.ClientCredentialGrant.main(ClientCredentialGrant.java:53)
Aug 02 2022 08:28 AM
It seems like your POP3 authentication command is incorrect?
The documentation says to use:
AUTH XOAUTH2
<base64 string in XOAUTH2 format>
For example:
[connection begins]
C: AUTH XOAUTH2
S: +
C: dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlYX
JlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1semRHRXVZMjl0
Q2cBAQ==
S: +OK User successfully authenticated.
[connection continues...]
Aug 02 2022 08:37 AM - edited Aug 02 2022 08:42 AM
I read somewhere you to need add the following the session. Not sure if that will help.
props.put("mail.pop3.auth.xoauth2.two.line.authentication.format", "true");
Aug 02 2022 07:47 PM - edited Aug 02 2022 08:15 PM
@DestryHines Thanks for pointing this out. For me, this command is executed internally from the JavaMail library functions. After reviewing your comment I tried to split the command into 2 lines using the property, "mail.pop3.auth.xoauth2.two.line.authentication.format" as true
Reference was taken from list of pop3 properties
But I am still unable to establish a connection with POP3 protocol. And getting the same error message.
Note: Updated the POP3 code in this post |
@jambo Thank you for suggesting me to apply this property. I have tried to implement it in my existing code but I haven't got any success in establishing a connection through POP3.
Apart from this property, I tried setting:-
Please let me know if any other parameters are required, or an existing parameter needs to be removed.
Aug 02 2022 08:44 PM
Aug 03 2022 03:27 AM
Aug 12 2022 01:50 AM
@borist2 Is that Bad user authenticated not connected issue fixed?
Aug 12 2022 06:47 AM
Aug 17 2022 04:03 PM
I'm having a similar problem, where a long running process must have access to send emails using @outlook.com on user's behalf.
After spending a couple days I found this small paragraph in the docs:
So, apparently the combination of client_credentials and SMTP is something that outlook.com doesn't really support.
I can't manage to get a token from my app registration with the correct scope.
Anyone here got it working?
Aug 17 2022 08:51 PM
Aug 30 2022 10:15 AM
Sep 01 2022 01:51 AM
Sep 07 2022 08:18 AM
Hi @manish1614
I had a similar problem with POP3 with the latest version of javax.mail (1.6.2)
However, I was looking at the documentation and the project move to jakarta mail. I replaced project dependency with jakarta.mail 1.6.7 and POP3 started to work.
Hopefully it can worked for you as well.