javax.mail.MessagingException: A3 BAD User is authenticated but not connected - jakarta-mail

I am trying to read mail from exchange server using IMAP protocol. I have implemented the code. But following exception occurs while executing the code.This exception occurs occasionally, I didn't get the reason why this is happening.
javax.mail.MessagingException: A3 BAD User is authenticated but not connected.;
nested exception is:
com.sun.mail.iap.BadCommandException: A3 BAD User is authenticated but not connected.
at com.sun.mail.imap.IMAPFolder.open(IMAPFolder.java:958)
at agent.client.attributeGroups.SendReceive.readMailAndReply(SendReceive.java:115)
at agent.client.attributeGroups.MailQueue.calculateTime(MailQueue.java:45)
at agent.client.MainClass$1.run(MainClass.java:72)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
code:
Properties props = new Properties();
props.put("mail.imap.auth", "true");
props.put("mail.imap.ssl.enable", "true");
props.put("mail.imap.host", "outlook.office365.com");
props.put("mail.imap.port", "993");
props.put("mail.transport.protocol", "imap");
props.put("mail.imap.auth.plain.disable", true);
props.put("mail.imap.auth.ntlm.disable", true);
props.put("mail.imap.auth.gssapi.disable", true);
//Get session object by passing credentials.
Session session = Session.getDefaultInstance(props,
new javax.mail.Authenticator(){
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
mailId, mailPass);}});
//Creating IMAP store and connecting it to Mailbox using credentials.
store = session.getStore("imap");
store.connect(mailId, mailPass);
//Getting mailbox mails.
inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);
int totalMailCount = inbox.getMessageCount();
//Reading all mails to Message array.
Message[] messages = inbox.getMessages(1, totalMailCount);
for (Message mail : messages)
{
Address[] fromAddresses = mail.getFrom();
String mailFrom = fromAddresses[0].toString();
String mailSubject = mail.getSubject();
System.out.println(mailFrom);
System.out.println(mailSubject);
mail.setFlag(Flags.Flag.DELETED,true);
}
}
}
Please suggest me suggestions to resolve this exception.

I have also faced that issue
You didn't close the connection,it always in open.
If you use Store and Inbox it always authenticated but not connected
It is authentication successfully but not connected because session is paradise.
You need to add below lines to your code.
First close the inbox after read
inbox.close(true);
Next close the store Connection
store.close();
If you close the estabilished connection correctly then it will connected according to the session.
Hope this really helpful for you

My problem was because I use a process to move emails from inbox to another different folder. I did it in batches because move big quantities emails throw Timeout exception, so I try to move small cquantities and I avoid the Timeout exception but started to get the BadCommandException: A2 BAD User is authenticated but not connected Exception. So I looking by an amount that worked for me. I got the idea base on this post
https://github.com/mscdex/node-imap/issues/689
It is a Microsoft's mechanism to shut down chatty clients. The
solution would be to login to this account less frequently.
It is due to a bug in the IMAP implementation. If the client presents a valid user name but an invalid password, the server
accepts the login, but subsequent commands fail with the
aforementioned error message.
It is a shared mailbox and you are using incorrect login scheme. Use Username#DomainName\SharedMailboxAlias for O365

This error message appears to be triggered when you've connected to an Exchange mail server (such as Office365) with a valid user and the correct password, but that user doesn't have permissions for the type of connection you made.
For example, I've seen several cases now where an IMAP connection was made, the system logged in with valid credentials, and the moment the first IMAP command was sent, the server said, "User is authenticated but not connected" and closed the connection.
To correct it, we went into the Exchange server or Office365 mail settings and ensured that the IMAP permission was checked for that user.

First,you should check the mail.imap.host value is equivalent to the email address's server.
If you use outlook OC
If true,you could then try to change the protocol to IMAPS
I hope the snippets that set of properties can help many that want to recieve mails.
sysProperties.put("mail.imap.starttls.enable", true);
MailSSLSocketFactory sf = null;
try {
sf = new MailSSLSocketFactory();
} catch (GeneralSecurityException e1) {
e1.printStackTrace();
}
sf.setTrustAllHosts(true);
sysProperties.setProperty("mail.imaps.auth.plain.disable", "true");
sysProperties.setProperty("mail.imaps.auth.ntlm.disable", "true");
sysProperties.put("mail.imap.ssl.socketFactory", sf);
sysProperties.setProperty("mail.imap.port", instance.getConfigPropertiesValue(configProperties, "mail.imap.port"));
sysProperties.setProperty("mail.imap.ssl.socketFactory.port", "993");
Session session = Session.getDefaultInstance(sysProperties, null);
Store store = null;
store = session.getStore("imaps");
store.connect("mail.serverhost", "mail.serverport"), "mail.username,"mail.password"));

Could it be related to your exchange settings? I ran into this error with imap and outlook.office365.com. I tried to set up the same account in Outlook to make sure it was working in general. Although I was able to add the account, when I actually tried to look at the inbox Outlook became unresponsive. So in my case, it was a problem with the account in general, not with how I was trying to connect.

It appears to be a bug in the office365 server. It's telling you that your password was wrong.

Related

SASL - LDAP: error code 49 - 80090303: LdapErr: DSID-0C09054F, comment: The digest-uri does not match any LDAP SPN's registered for this server

I'm trying to update the user password for a user in Microsoft Active Directory with LDAP, using JNDI library over SASL (DIGEST-MD5). And there are a couple of issues that makes the operation fail.
First issue
During the authentication phase, I receive the error
Exception: #javax.naming.AuthenticationException: [LDAP: error code 49 - 80090303: LdapErr: DSID-0C09054F, comment: The digest-uri does not match any LDAP SPN's registered for this server., data 0, v2580
Steps taken
I added the required SPN to the DC in AD, and the issue was resolved only for one time, then it came back. When I checked the DC, I found out that the SPN that I have just added has been removed. And this keeps happening every time I add the SPN to the DC!
Second issue
During the time that the authentication proceeds successfully, the server refuses to update the user's password. I'm trying to update the "unicodePwd" attribute using a "DirContext.REPLACE_ATTRIBUTE" operation (I'm using a domain controller administrator account for the authentication, and trying to update a normal user account).
This is the error I receive "Error:
#javax.naming.OperationNotSupportedException: [LDAP: error code 53 - 0000001F: SvcErr: DSID-031A12D2, problem 5003 (WILL_NOT_PERFORM), data 0 ]; remaining name '<the DN of the user that I was trying to update>'
Another note, when I check the attribute "unicodePwd", it's always unset!! So, the question here "How does the AD authenticate the user? Which attribute holds the user's password?!!
Third issue
I can use a couple of LDAP clients, and I can update/reset the user's password. I only need to specify the authentication protocol as (SASL) and the operation goes seamlessly =, without having to make any Changes to the AD/SC!
This is the code sample I'm using
// Session variables
String adminUsername = "<administrator sAMAccountName value>";
String adminPwd = "<admin password>";
String userDN = "<DN for the user being updated>";
String newPwd = "<The new password for the user being updated>";
String ipAddress = "<AD ip address>";
// LDAP configuration
String securityProtocol = "sasl";
String providerURL = "ldap://" + ipAddress;
Hashtable<Object, Object> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put("javax.security.sasl.strength", "high");
env.put("javax.security.sasl.policy.noplaintext", "true");
env.put(Context.PROVIDER_URL, providerURL);
env.put(Context.SECURITY_AUTHENTICATION, "DIGEST-MD5");
env.put(Context.SECURITY_PRINCIPAL, adminUsername);
env.put(Context.SECURITY_CREDENTIALS, adminPwd);
env.put(Context.SECURITY_PROTOCOL, securityProtocol);
env.put(Context.REFERRAL, "follow");
// Prepare the modifications list
String newQuotedPassword = "\"" + newPwd + "\"";
byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
ModificationItem[] mods = new ModificationItem[1];
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
new BasicAttribute("unicodePwd", newUnicodePassword));
// Initiate the LDAP connection
LdapContext ctx = new InitialLdapContext(env, null);
// Modify the password
ctx.modifyAttributes(userDN, mods);
// Close LDAP connection
ctx.close();
Your help is much appreciated.
So, after a good deal of R&D. There is no way to update the password in the AD without using SSL. Java and MS AD are very strict on that.

OWIN Invalid URI: The Uri String is too long

I have an MVC application hosted on a server (IIS) which points to 3 SQL databases. This has been running without issues for months.
I've just had to change the connectionstrings for all 3 SQL databases to point to new databases.
Now when I try to log in I get the following error..
The connection strings are using Windows Authentication and this account is set in the AppPool. I've also manually tried to connect to each database instance with the account and this works fine. I'm beginning to think the change is SQL connections is just a red herring.
In terms of the error message, I totally understand what the error is Im just not sure why its being thrown. The only thing I can think of is I'm in some kind of redirect loop which is appending the URL.
It definitely feels like an IIS issue but I can't put my finger on it.
Has anyone come across this before with OWIN or can advise on debugging steps that might diagnose the issue?
Startup.cs
public partial class Startup
{
private static bool IsAjaxRequest(IOwinRequest request)
{
IReadableStringCollection query = request.Query;
if ((query != null) && (query["X-Requested-With"] == "XMLHttpRequest"))
{
return true;
}
IHeaderDictionary headers = request.Headers;
return ((headers != null) && (headers["X-Requested-With"] == "XMLHttpRequest"));
}
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context, user manager and role manager to use a single instance per request
app.CreatePerOwinContext(ParentDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
app.CreatePerOwinContext(PrincipalManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
// Configure the sign in cookie
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity =
SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, Guid>(
TimeSpan.FromMinutes(int.Parse(WebConfigurationManager.AppSettings["RefreshInterval"])),
(manager, user) => manager.GenerateUserIdentityAsync(user),
claim => new Guid(claim.GetUserId())),
OnApplyRedirect = ctx =>
{
if (!IsAjaxRequest(ctx.Request))
{
ctx.Response.Redirect(ctx.RedirectUri);
}
}
}
});
}
}
After hours of investigation I eventually found the issue.
The issue was the number of claims being added for a user. Once we reduced the number of claims it started working again.
The most likely cause is that you're stuck in an error loop. If the authentication to the database where the users is stored is failing then you will get sent to the error page which will try to run the authentication again and fail and send you to the error page, again and again. Each pass it would append to the previous url eventually reaching this state.

ValidateCredentials LDAP server unavailable

Currently I am using PrincipalContext class to call the ValidateCredentials method to check for user credentials. It was working fine with our 2 environment until a rather 'strange' error occurred.
var configuration = ConfigurationManager.GetSection("PrincipalContextConfiguration") as PrincipalContextConfigurationSection;
var principalContext = new PrincipalContext(configuration.ContextType, configuration.Name, configuration.Container);
principalContext.ValidateCredentials(userName, password);
configuration.ContextType = "Domain"
configuration.Name = "example.local"
configuration.Container = "CN=Users,DC=example,DC=local"
Above are the sample of our current code, simplified for easier viewing. As above, everytime we need to validate credential, we will create a new PrincipalContext.
The error that we have is this validate credential works fine if we provide a valid username and password. But for a specific machine, that throws this error, whenever invalid username and password is supplied, exception is thrown with a message "LDAP server is unavailable".
Could anyone point me to where I should start to find the root cause of this. It is strange to us that the method is only throwing that exception when username and password is incorrect. we verify this by using PowerShell to call the method.
And I am not that expert in AD. Thanks.

D3 Connection issue using mvsp java api

I am trying to connect to D3 Database with MVSP java api. So far:
I have downloaded the mvapi.jar
added it in project lib folder
written the sample code for connection inside main method
String url = "jdbc:mv:d3:hostname:portNo";
Properties props = new Properties();
props.setProperty("username", "");
props.setProperty("password", "");
String account = "AGCO";
String password = "";
MVConnection connection = null;
try {
// Getting error at this point
connection = new MVConnection(url,props);
MVStatement mvStatement = connection.createStatement();
connection.logTo(account,password);
MVResultSet results = mvStatement.executeQuery(query);
}
com.tigr.mvapi.exceptions.MVException: server error with errorCode 1023.
I checked the console but I'm not able to figure out the actual cause or whether I am entering the wrong username, password.
Please suggest what I am doing wrong.
First, you have to set a breakpoint or trace which function is throwing the errors. Then check the routes, (FileName) probably you will have much more experience than I do, but keep in mind that giving the full route ("account,filename," where the last comma is important) is never a bad idea while keep you safer and is mandatory if the filename is in a different account that you are logged to.
And like always please verify these things:
You have enough licenses. Try to close any terminal you have opened for testing your queries. Yes you know is true. One connection one license. Sometimes MVSP let you two under the same IP but chek this.
MVSP service is running. See Pick D3 documentation.
Your USER and ACCOUNT are both ENABLED to access in the MVSP server otherwise you won't be able to access these files or login with the user through the API. See the documentation to enable in the MVSP.Menu account.
I hope this helps.

Email verification through silverlight

I've built a Silverlight website where users can create an account and login. Right now, users just create an account through a form and can directly login. I want to incorporate a email verification feature, where the user will receive an email with a verification URL and only then can he login. I also wish to incorporate a forgot password feature that sends an email to the users registered email address to recover password.
How can I do this in silverlight. I'm using Windows SQL Azure as the back-end database. Will I have to create a separate Application for creating user accounts and recovering passwords?
Hope this helps you out on part A of your problem.
I noticed the post might throw you off a bit, so I decided to write a method that will do this for you in the quickest amount of time.
public bool Send(string fromEmail, string toEmail, string subject, string body)
{
try
{
MailMessage message = new MailMessage();
message.From = new MailAddress(fromEmail);
message.To.Add(new MailAddress(toEmail));
message.Subject = subject;
message.Body = body;
message.IsBodyHtml = false;
SmtpClient smtp = new SmtpClient();
smtp.EnableSsl = true;
smtp.Send(message);
return true;
}
catch (Exception ex)
{
return false;
}
}
Essentially, once they create their account you would want to call this filling out all variables. Make sure in your body of text you have a link that sends them to a page where they can submit "activate" their account.
This will essentially be a bit value in the database that is set to false by default and won't be set to true until they click on the "submit" or "activate" button from the link that would be in the body of text.
For password recovery you would do the same. Except instead of sending them to a page to activate their account you'd send them to a page where they could just re-create their password. Since the database doesn't care if the password is old or new you could just send them to a page where they create a new password. You wouldn't even need to create a temp password for them (Unless you wanted to for experience and for a extra caution).
Happy Coding! ;)

Resources