Spring Email: Must issue a STARTTLS command first - spring

I am trying to send a simple email to myself using Spring Email, but I'm encountering the following exception:
org.springframework.mail.MailSendException: Failed messages: com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first. p4sm7233776wrx.63 - gsmtp
; message exceptions (1) are:
Failed message 1: com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first. p4sm7233776wrx.63 - gsmtp
By googling it I saw that most people fixed this by adding the property spring.mail.properties.mail.smtp.starttls.enable=true, but I have already done it and isn't working in my case.
My application.properties:
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=myEmail#gmail.com
spring.mail.password=********
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.auth=true
My code:
#Service
#Slf4j
public class NotificationService {
#Autowired
private JavaMailSender javaMailSender;
public void sendNotification() {
SimpleMailMessage messaggio = new SimpleMailMessage();
messaggio.setTo("myEmail#gmail.com");
messaggio.setFrom("YourSpringFriend#gmail.com");
messaggio.setSubject("Test Spring Email");
messaggio.setText("Tadaaaa! Email da Spring!");
javaMailSender.send(messaggio);
}
}
What am I doing wrong?
Thanks in advance for your time and experience

Add this property in your application.properties
spring.mail.properties.mail.smtp.starttls.enable=true
This work fine

Related

How to display validation error messages and codes in a Spring WebFlux Rest API

I'm using Spring Web MVC in a Reactive SpringBoot Application, and wrote a custom validator. In case of a validation error, a 400 response code is used, which is fine, but then AbstractErrorWebExceptionHandler catches this and spits out
{
"timestamp": 1651678946524,
"path": "/signup",
"status": 400,
"error": "Bad Request",
"requestId": "0f61cb96-1"
}
which is not very useful to the client. How can I display the error messages and codes? I know they are available, because they are logged:
DEBUG 32475 --- [ parallel-1] a.w.r.e.AbstractErrorWebExceptionHandler : [0f61cb96-1] Resolved [WebExchangeBindException: Validation failed for argument at index 0 in method: public reactor.core.publisher.Mono<...with 1 error(s): [Field error in object 'userSignup' on field 'username': rejected value [matilda0]; codes [username.exists.userSignup.username,username.exists.username,username.exists.java.lang.String,username.exists]; arguments []; default message [null]] ] for HTTP POST /signup
Any help would be appreciated, thank you.
This is what I did:
private void validate(SomeEntity someEntity) {
Errors errors = new BeanPropertyBindingResult(someEntity, "SomeEntity");
validator.validate(someEntity, errors);
if (errors.hasErrors()) {
throw new ServerWebInputException(errors.toString());
}
}
Validator is injected:
private final Validator validator;
private final SomeEntityDao dao;
public SomeEntityHandler(
Validator validator,
SomeEntityDao dao
) {
this.validator = validator;
this.dao = dao;
}
Project: WebFluxR2dbc
Adding
server.error.include-binding-errors=ALWAYS
in application.properties seems to fix it, although it still doesn't look up the message code properly. To actually get the error message itself to appear in the response, I had to wire in a MessageSourceAccessor in my Validator and use that as the default message!
errors.rejectValue("username","username.exists",msgs.getMessage("username.exists"))
So I must still be missing something, but this will work for now.

sudden gmail smtp authentication failure when using app password

So I am trying to set up a spring boot app to send out automated emails. I have created a gmail account specifically for this purpose. I followed a tutorial which directed me to set up two factor authentication for my gmail account, and set up an app password to login. I did this and everything worked fine, I sent a test email from the app and it worked. HOWEVER without making any code changes I tried the proccess again a few hours later and I got the following message:
Exception in thread "main" org.springframework.mail.MailAuthenticationException: Authentication failed; nested exception is javax.mail.AuthenticationFailedException: 534-5.7.9 Please log in with your web browser and then try again. Learn more at
534 5.7.9 https://support.google.com/mail/?p=WebLoginRequired v8-20020a05683018c800b005cb39fc3e15sm11417144ote.13 - gsmtp
Here is my application.properties file:
spring.mail.protocol=smtp
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=
spring.mail.password=
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
mail.smtp.debug=true
and here is my mail service (although this error occurs at app startup so I dont think its the cause)
#Service("mailService")
public class MailServiceImpl implements MailService {
#Autowired
private JavaMailSender mailSender;
public void sendEmail(Mail mail) {
MimeMessage mimeMessage = mailSender.createMimeMessage();
try {
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
mimeMessageHelper.setSubject(mail.getMailSubject());
mimeMessageHelper.setFrom(new InternetAddress(mail.getMailFrom(), "tyler"));
mimeMessageHelper.setTo(mail.getMailTo());
mimeMessageHelper.setText(mail.getMailContent());
mailSender.send(mimeMessageHelper.getMimeMessage());
} catch (MessagingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
I have tried following the link for advice but it recommends I use an app password (which I already am) or to enable "less secure apps" (which I cant as a 2FA user). Any help would be greatly appreciated.

javax.mail.MessagingException: Could not connect to SMTP host or don't receive any email when using ionos

I have spring boot application and want's to send eamil using ionos. these are email configuration that i used:
#Configuration
public class MailConfiguration {
#Autowired
private Environment env;
#Bean
public JavaMailSender getMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost(env.getProperty("spring.mail.host"));
mailSender.setPort(Integer.parseInt(env.getProperty("spring.mail.port")));
mailSender.setUsername(env.getProperty("spring.mail.username"));
mailSender.setPassword(env.getProperty("spring.mail.password"));
return mailSender;
}
}
spring:
mail:
host: smtp.ionos.com
port: 465
username: support#mysite.com
password: password
with 465 port i get this error:
javax.mail.MessagingException: Could not connect to SMTP host: smtp.ionos.com, port: 465, response: -1
and with 587 port, i didn't get any error, but also didn't receive any email email in inbox.
If you're still stuck on this. Please check your DNS record with Ionos staff to make sure everything is as it should be and then - if it still isn't working, use Dror's answer from here because it worked for me.
Basically, the errors from Ionos are a red herring. You need to set the from field in your JavaMailSender method:
helper.setFrom(your email here);
It's easy to overlook this because Gmail has looser sec protocols and doesn't need it.
Hope that helps.

Spring SAML sending wrong AuthNRequest

stuck with this problem since long, any help is appreciated.
I am implementing Spring SAML SSO authentication for my application.
It's actually a huge security configuration file therefore I will attach only configuration part that I think could be important.
#Bean
public MetadataGenerator metadataGenerator() {
MetadataGenerator metadataGenerator = new MetadataGenerator();
metadataGenerator.setEntityId(env.getProperty("saml.entity.id"));
metadataGenerator.setExtendedMetadata(extendedMetadata());
metadataGenerator.setIncludeDiscoveryExtension(false);
metadataGenerator.setKeyManager(keyManager());
return metadataGenerator;
}
#Bean
#Qualifier("idp-ssocircle")
public ExtendedMetadataDelegate ssoCircleExtendedMetadataProvider() throws MetadataProviderException {
String idpSSOCircleMetadataURL = env.getProperty("saml.provider.url");
HTTPMetadataProvider httpMetadataProvider = new HTTPMetadataProvider(this.backgroundTaskTimer, httpClient(),
idpSSOCircleMetadataURL);
httpMetadataProvider.setParserPool(parserPool());
ExtendedMetadataDelegate extendedMetadataDelegate = new ExtendedMetadataDelegate(httpMetadataProvider,
extendedMetadata());
extendedMetadataDelegate.setMetadataTrustCheck(true);
extendedMetadataDelegate.setMetadataRequireSignature(false);
backgroundTaskTimer.purge();
return extendedMetadataDelegate;
}
Values of the property file we have used in this bean is -
saml.entity.id=urn:saml2:test:s
saml.provider.url=https://fedsvc-stage.pwc.com/ofiss/FederationMetadata/2007-06/FederationMetadata.xml
My spring application is hosted on local machine and IDP is publically available. I have added entry in my hosts file so my ip is mapped with mysso.com
Now I am trying to access a url that is behind SAML authentication -
http://mysso.com:8080/sso-self/auth/login
User get's redirected to the IDP where he input credentials and after successfull authentication user get's redirected back to -
http://localhost:8080/sso-self/saml/SSO, with saml response but I get 404 on the browser, and following error on console -
org.opensaml.common.SAMLException: InResponseToField of the Response doesn't correspond to sent message a330ei589j3e99ee10d8a55bghc518i
The problem I can see is message is being stored and retrieved from 2 different session as first request came from domain name mysso.com but response is coming back to localhost
here is my AuthnRequest XML that is being sent to IDP
<?xml version="1.0" encoding="UTF-8"?><saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://localhost:8080/madison-sso-self/saml/SSO" Destination="https://fedsvc-stage.pwc.com/ofiss/" ForceAuthn="false" ID="a345ia5236e6hc2g48ea13fcf4386h7" IsPassive="false" IssueInstant="2018-12-18T07:46:41.812Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">urn:saml2:test:s</saml2:Issuer>
</saml2p:AuthnRequest>
All I could understand is AssertionConsumerServiceURL value in AuthnRequest is http://localhost:8080/madison-sso-self/saml/SSO and that's why it's coming back to this url.
Now I don't understand why this value is localhost instead of my hostname which is http://mysso.com:8080/madison-sso-self/saml/SSO.
Please reply incase you need some more information to figure it out.
Thanks in advance.
You can use SAMLContextProviderLB to fix this issues. Please replace the values in below configuration with your server URL.
#Bean
public SAMLContextProviderLB contextProvider() {
SAMLContextProviderLB samlContextProviderLB = new SAMLContextProviderLB();
samlContextProviderLB.setScheme("https");
samlContextProviderLB.setServerName("www.myserver.com");
samlContextProviderLB.setServerPort(443);
samlContextProviderLB.setContextPath("/spring-security-saml2-sample");
samlContextProviderLB.setStorageFactory(new EmptyStorageFactory());
return samlContextProviderLB;
}
The above configuration will use https://www.myserver.com/spring-security-saml2-sample/saml/SSO on redirecting from SAML service provider.
samlContextProviderLB.setStorageFactory(new EmptyStorageFactory());
The above line will help to fix the multiple sessions issue.
Please see the following paragraph in "spring-security-saml" documentation:
https://docs.spring.io/autorepo/docs/spring-security-saml/1.0.x-SNAPSHOT/reference/htmlsingle/#chapter-troubleshooting
Error 'InResponseToField doesn't correspond to sent message' during SSO
Make sure that application uses the same HttpSession during sending of the request and reception of the response. Typically, this problem arises when the authentication request is initialized from localhost address or http scheme, while response is received at a public host name or https scheme. E.g., when initializing authentication from URL https://host:port/app/saml/login, the response must be received at https://host:port/app/saml/SSO, not http://host:port/app/saml/SSO or https://localhost:port/app/saml/SSO.
See if you can access the application using same public DNS name instead of localhost

Spring : Unable to send mail- Could not connect to SMTP host: smtp.gmail.com, port: 465, response: -1

I am trying to send an email through my spring boot app. However, I am getting the following exception:
Could not connect to SMTP host: smtp.gmail.com, port: 465, response: -1
The controller class is as follows :
#RestController
#RequestMapping("/services")
public class MyController {
#Autowired
private MailSender mailSender;
#RequestMapping(value = "/my/mail", method = RequestMethod.GET)
#ResponseBody
public String sendmymail() {
System.out.println("Starting send");
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setSubject("Hello");
mailMessage.setTo("myemailid#gmail.com");
mailMessage.setFrom("myemailid#gmail.com");
SimpleMailMessage message = new SimpleMailMessage(mailMessage);
message.setText("Hello");
try {
this.mailSender.send(message);
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
System.out.println("Finished send");
return "OK";
}
}
I have configured the properties in application.properties as follows :
spring.mail.host=smtp.gmail.com
spring.mail.port=465
spring.mail.username=<myemailid>
spring.mail.password=<mypassword>
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.transport.protocol=smtps
spring.mail.properties.mail.smtps.quitwait=false
spring.mail.properties.mail.smtp.socketFactory=25
I have added the folllowing dependecy in pom.xml for autowiring MailSender:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
Is there anything that I am doing wrong. The email id and password is correct, as I have checked it multiple times.
Port number for google smtp server is 587:
spring.mail.port=587
Maybe add this too:
spring.mail.properties.mail.smtp.starttls.enable = true
I managed to send emails with my gmail account without these three config values:
spring.mail.properties.mail.transport.protocol=smtps
spring.mail.properties.mail.smtps.quitwait=false
spring.mail.properties.mail.smtp.socketFactory=25
I have no idea what are they but guess you should be ok without them.
I faced similar issue. I followed below 2 steps & it worked -
In gmail settings, Turn ON access for less secure app.
Antivirus settings. Turn off web-shield and mail-shield.

Resources