AuthenticationError in reading mail using IMAP protocol using JavaMail - authentication

I am trying to read emails from XXX domain using Java Mail API. I am able to login and read the email using IMAPS protocol using PUTTY from server.
However from Java, I am getting Authentication Error:
Following is the screenshot where I am able to connect from PUTTY:
Following is my Code:
Properties properties = new Properties();
properties.put("mail.imap.host", "hostname");
properties.put("mail.imap.port", "993");
Session session = Session.getDefaultInstance(properties, new javax.mail.Authenticator()
{
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication("username", "password");
}
});
Store store = session.getStore("imaps");
store.connect("username", "password");
What does making it stop to read mail from Java ?
Internally, mail domain is using outlook exchange server.
Username being passed is full xxxx#domain.com.

You can remove the property settings; they have no effect since you're using imaps. And you can get rid of the Authenticator since you're passing the username and password explicitly.
You need to pass the host explicitly as well, otherwise it's connecting to localhost, which may be why it's failing. Look at the JavaMail debug output to see what it's actually doing. If that doesn't solve your problem, post the debug output.

Related

Can't authenticate with SMTP (but IMAP works) Microsoft 365

I'm trying to create an 'automation#mydomain.com' email account, which will be used to send out email alerts from my code. Since the days of 'basic authentication' are done, I'm implementing this with 'modern authentication'. Everything is hosted in Microsoft 365. Authentication is using the latest MSAL. Email is handled using the recommended MailKit library.
The Code
This code is trying to do four things:
Read a certificate from a file.
Use that certificate to get an authentication token from Microsoft.
Test that token and the configuration by opening an IMAP connection to the desired inbox and reading out the number of messages inside.
Send an email.
Dim AuthCert = New X509Certificate2(CertPath, EmailSettings("AuthCertPassword"), X509KeyStorageFlags.PersistKeySet)
AuthClient = ConfidentialClientApplicationBuilder.Create(EmailSettings("ApplicationID")).
WithAuthority(AzureCloudInstance.AzurePublic, EmailSettings("TenantID")).
WithCertificate(AuthCert).
Build
Dim AuthResult = AuthClient.AcquireTokenForClient({"https://outlook.office365.com/.default"}).ExecuteAsync.Result
Dim EmailMessage As New MimeMessage
EmailMessage.From.Add(New MailboxAddress(Nothing, Config.EmailSenderAddress))
For Each R In Config.EmailRecipients
EmailMessage.To.Add(New MailboxAddress(Nothing, R))
Next
EmailMessage.Body = New TextPart("plain") With {.Text = Warning}
Using MailClient As New ImapClient
MailClient.Connect("outlook.office365.com", 993, SecureSocketOptions.SslOnConnect)
Log.WriteEntry($"Token length is: {AuthResult.AccessToken.Length}")
Dim Authentication As New SaslMechanismOAuth2(Config.EmailSenderAddress, AuthResult.AccessToken)
MailClient.Authenticate(Authentication)
MailClient.Inbox.Open(MailKit.FolderAccess.ReadOnly)
Log.WriteEntry($"IMAP worked. Inbox count is {MailClient.Inbox.Count}")
MailClient.Disconnect(True)
End Using
Using MailClient As New SmtpClient
MailClient.Connect("smtp.office365.com", 587, SecureSocketOptions.StartTls)
Dim Authentication As New SaslMechanismOAuth2(Config.EmailSenderAddress, AuthResult.AccessToken)
MailClient.Authenticate(Authentication)
MailClient.Send(EmailMessage)
MailClient.Disconnect(True)
End Using
The above code almost works.
Read certificate file ✔
Get a working authentication token ✔
Connect via IMAP to read number of emails in the inbox ✔
Send an email via SMTP ✖
The error message is:
MailKit.Security.AuthenticationException: 535: 5.7.3 Authentication unsuccessful [BN9PR03CA0500.namprd03.prod.outlook.com 2023-01-26T16:58:30.103Z 08DAFF3B69EFD03B]
It occurs on the line: MailClient.Authenticate(Authentication) in the Smtp section.
Note that this same exact authentication succeeded when used for IMAP.
The M365 Config
I have followed two Microsoft articles in setting up my cloud-side configuration. The first article is:
Authenticate an IMAP, POP or SMTP connection using OAuth
I have registered the application and given it the required API permissions:
I don't have to worry about the workings of SASL XOAUTH2 because the MailKit library implements that for me.
I have created the 'service principal' using the New-ServicePrincipal command (using the correct Object ID from the Enterprise Application node). And have run the Add-MailboxPermission command to grant that principal access to the mailbox.
I have also followed the steps from this article:
Enable or disable authenticated client SMTP submission (SMTP AUTH) in Exchange Online
SMTP Authorization is disabled at the organization level. But that setting has been overridden for this specific mailbox using the Set-CASMailbox command.
So, what am I missing?
It might be temporary server issue with Microsoft OAuth that is ongoing for several day now. Many many reports from ppl with different email clients report for the same issue. For example
https://support.emclient.com/index.php?/Knowledgebase/Article/View/256/7/cannot-send-emails-for-outlookcom-accounts---authentication-aborted

Authenticating Domino REST Service Requests

I have installed "Domino Sample REST Service Feature" from 901v00_11.20141217-1000 version of XPages Extension Library. OpenNtfSample service (com.ibm.domino.services.sample.service.SampleService) works as it should in general and the only problem with it that it completely ignores authentication settings of the server.
I have tried both Basic and Session Authentication as described in Authenticating Domino REST Service Requests and the result I get is the following - the service returns data always and does not ask for any user name and password.
The server is configured with Session Authentication now and I get password prompt when I try to access
{my_server}/api/data
but does not get it when I open
{my_server}/api/sample
After I had added this Web Site Rule
Description: DAS service
Type of rule: Override Session Authentication
Incoming URL pattern: /api/
the server changed password prompt for
{my_server}/api/data
but
{my_server}/api/sample
remained open.
Has anybody experienced this kind of error? Can anybody help me password protect this sample service so that I could start developing my own once based this example?
The /api/sample resource is wide open on purpose. That just returns a link to the contacts resource -- /xpagesext.nsf/api/sample/contacts.
If you really want to prevent anonymous access to the /api/sample resource, there are two possible solutions: 1) Disable anonymous access for all HTTP requests, or 2) Make a change to the RootResource class. The first solution is a server config change. I'm sure you can find details about that elsewhere. Since this is StackOverflow, I'll focus on the second solution.
As you have already noticed, we don't allow anonymous access to the /api/data resource. You can mimic that behavior in the /api/sample resource with a simple change to RootResource.getLinks(). Near the top of the method, just add these lines of code:
boolean authenticated = false;
Session session = ContextInfo.getUserSession();
if ( session != null ) {
String userName = session.getEffectiveUserName();
if ( userName != null && !userName.equals("Anonymous")) {
authenticated = true;
}
}
if ( !authenticated ) {
throw new NoAccessSignal("Need user context");
}
By the way, you won't need to make the same change to the contacts resource class (ContactsListResource.java). Because the contacts resource URL includes a database name (xpagesext.nsf), the web server will attempt to open the database before forwarding the request to the REST service. You can prevent anonymous access to the contacts resource by changing the ACL of xpagesext.nsf. Just make sure the default access is "No access".

Remote service call through proxy

I'm trying to make a very simple service call from VS2012.
The service is on a domain outside a proxy and requires logon credentials.
I have set a refrence to the service in visuals studio. At that point i entered in the remote domian username and password and VS created all the proxy classes for me.
I then added this line to appconf file.
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="true">
</defaultProxy>
</system.net>
Which i believe will allow me to get through our proxy using my own credentails
I then wronte this simple piece of code
private void GetData()
{
OASIS.OasisServiceSoapClient o = new OASIS.OasisServiceSoapClient();
o.ClientCredentials.UserName.UserName = #"OtherDimain\UserName";
o.ClientCredentials.UserName.Password = "Password";
var d = o.SelectOfficersAll();
}
and of course it didn't work and i got all the errors that everyone has posted on.
So first question is
do i need to add this
o.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
because i did and still get that same stupid error
"The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Negotiate,NTLM'."
and inner exception
"{"The remote server returned an error: (401) Unauthorized."}"
so am i getting through the proxy ?
Am i using my own credentials ?
Am i passing the right paramaters in to the Service Model ?
Some examples show the username and password properties in the code above are to impersonate the current job.
But i read these on the MSDN page as being the credentials you want to use on the remote serve. The Help topic is ambigious. And if i don't enter them here then how ?
I'm trying to do something so simple , yet can't seem to get past this point.
Ok thanks to my Colleague Sean. It seems that depending on wether you are calling a web service or a WCF services determines what you need to do.
So as a web service this works
OASISWeb.OasisService s = new OASISWeb.OasisService();
s.Credentials = new System.Net.NetworkCredential("Username", "Password", "Domain");
var d = s.SelectOfficersAll();
DataSet x = (DataSet)d;
if it's a WCF service then you need this
var service = new OasisTest2.ServiceReference1.OasisServiceSoapClient();
System.Net.WebRequest.DefaultWebProxy.Credentials = system.Net.CredentialCache.DefaultNetworkCredentials;
service.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential("Username", "Password", "Domain");
var result = service.SelectOfficersAll();
It seems that WebRequest is a global object and you need to set the DefaultWebProxy.Credentails on it.
How you are suppose to know that ? I never found any reference to it when i searched on how to connect to a WCF service on MSDN. Must be a secret. So keep it under your hat.

Sending eMail Through Visual C++/Cli Not Working

I'm trying to send an email using C++/Cli through gMAil ... This is the code but it is not working , any suggestions?
MailMessage^ email=gcnew
MailMessage("from#From.com","to#to.com","SUBJECT","MESSAGE");
SmtpClient^ smtp=gcnew SmtpClient("smtp.gmail.com", 587);
smtp->EnableSsl=true;
smtp->UseDefaultCredentials = false;
smtp->Credentials = gcnew
System::Net::NetworkCredential("from#from.com","password");
smtp->Send(email);
First a small comment: You are not using C++, you are using C++/CLI (.NET).
For a solution, see answer of: SmtpClient wont authenticate over SSL/TLS (not pointing to gmail)
Alternatively: How can I send emails through SSL SMTP with the .NET Framework?
If you have a proxy server, you are normally without luck... of course, you can try to specify a proxy server in your config file. For more info see:
Is it possible to specify proxy credentials in your web.config?
But normally your proxy server will not allow CONNECT reqeusts...

PowerShell send SMTP email without (default) authentication

I am attempting to deliver an email to an Exchange-server using PowerShell. My goal is to use plain old SMTP to deliver a message to a local user (mailbox) on the Exchange-server. The Exchange-server is located within the same network and AD-domain as the sending server and as the logged on sending user.
However the user I am sending from does not have access to send emails on that Exchange-server. And PowerShell seems to send authentication using the logged on user credentials by default.
$smtp = new-object Net.Mail.SmtpClient("exchangeserver.mylan")
$smtp.Send($emailFrom, $emailTo, $subject, $message)
I have tried to add $smtp.UseDefaultCredentials = $false before the $smtp.Send(... line without success.
One solution would be to allow this user to send messages on the Exchange server. However the user will change depending on what service is running this script, so I don't want to solve it that way.
Another solution would be to hardcode credentials using something like $smtp.Credentials = New-Object System.Net.NetworkCredential("DOMAIN\user", "password") (also before $smtp.Send(... line). I've had no luck in this either.
The solution I'd really like is to just send email in PowerShell anonymously using good old auth free SMTP.
1) Create new Receive Connector
2) Enable anonymous authentication on it
3) Lock it down to IP address of the computer you are running the script on
I realize this is old, but I'm surprised there isn't an answer here for this. I was confused initially because I have some similar code I wrote in C# and it works just fine. It seems PowerShell will default to using someone's credentials. I won't assume it's who runs the script, but it could be.
When I'm building up the credential object, I pass in a space for the username and password and that seems to work fine.
$credential = New-Object System.Management.Automation.PSCredential (" ", " ")
If I completely leave out the credential part then it will use someone's credentials or something. Until now I was getting the following message:
The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.1 Client was not authenticated
I hope this helps someone with such an odd problem.