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

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.

Related

Spring JAVA SSL - No name matching localhost found

I have two SSL end-points that share the same application.properties and key store file.
I want to have one end-point call the other, but getting an error No name matching localhost found
How can I adjust this to allow one microservice to call the other(s) as intended below?
I have played with the following to attempt a solution to no avail:
javax.net.ssl.HostnameVerifier()
Created a localhost certificate and added it to the keystore
#CrossOrigin(origins = "*", maxAge = 3600)
#RestController
public class submitapplicationcontroller {
#Bean
public WebClient.Builder getWebClientBuilder(){
return WebClient.builder();
}
#Autowired private WebClient.Builder webClientBuilder;
#PostMapping("/submitapplication")
public String submitapplication() {
/*** Returns Error Found Below ***/
String response = webClientBuilder.build()
.post()
.uri("https://localhost:8080/validateaddress")
.retrieve()
.bodyToMono(String.class)
.block();
return response;
}
}
javax.net.ssl.SSLHandshakeException: No name matching localhost found
at java.base/sun.security.ssl.Alert.createSSLException
Error has been observed at the following site(s):
|_ checkpoint ⇢ Request to POST https://localhost:8080/v1/validateaddress
#CrossOrigin(origins = "*", maxAge = 3600)
#RestController
public class validateaddresscontroller {
#PostMapping("/validateaddress")
public String validateaddress() {
return "response";
}
}
server.ssl.key-alias=server
server.ssl.key-password=asensitivesecret
server.ssl.key-store=classpath:server.jks
server.ssl.key-store-provider=SUN
server.ssl.key-store-type=JKS
server.ssl.key-store-password=asensitivesecret
The problem here was the way I went about creating and implementing the certificates. I had 2 separate keystores and certificates; one named "server", and one named "localhost". I added the localhost certificate to the server keystore, and applied the server keystore and certificate to the springboot application / application.properties.
What you have to do is create just one certificate and keystore dubbed "localhost" and you have to use that to apply to the application / application.properties.
What you should have after creating the localhost JKS and certificate
server.ssl.key-alias=localhost
server.ssl.key-password=asensitivesecret
server.ssl.key-store=classpath:localhost.jks
server.ssl.key-store-provider=SUN
server.ssl.key-store-type=JKS
server.ssl.key-store-password=asensitivesecret
Note: I don't believe you actually have to create a JKS named "localhost", just the certificate. I just did for testing purposes.

Spring Boot: Connection timed out when trying to call a service from a service

I have 2 microservices + an Eureka Server in which they are registerd.
I made really everything I could think of, yet when I try to call the login service from the manager service, I always get "Connection timed out".
POST http://localhost:9903/login
{
"username":"adm4",
"password":"adm4adm4"
}
I have tried to work with Spring RestTemplate and WebClient and also Apache HttpClient.
All the times, the flow reaches the post method, and I get the same result.
I guess it must be some configuration issue.
I am working on localhost with all modules.
It really drives me crzay!
Please advise. I appreciate it.
The relevant info is as follows. Please tell me if you need more info.
First of all you can see that the services are registered and up:
Next the code:
Manager (calling) Service:
(I left inside all my previous attempts commented)
#PostMapping("/login")
public void login(#RequestBody LoginRequest loginRequest) throws Exception {
String url = getBaseUrl("bbsim-login-service") + "/api/auth/signin";
/* CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpPost httpPost = new HttpPost(getBaseUrl("bbsim-login-service") + "/api/auth/signin");
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("username", loginRequest.getUsername()));
params.add(new BasicNameValuePair("password", loginRequest.getPassword()));
httpPost.setEntity(new UrlEncodedFormEntity(params));
CloseableHttpResponse response = httpclient.execute(httpPost);
System.out.println(response.getStatusLine().getStatusCode());
} finally {
httpclient.close();
}
*/
/* HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
// Connect timeout: time is in milliseconds
clientHttpRequestFactory.setConnectTimeout(30000);
// Read timeout: time is in milliseconds
clientHttpRequestFactory.setReadTimeout(30000);
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
HttpEntity<LoginRequest> request = new HttpEntity<>(loginRequest);
JwtResponse res = restTemplate.postForObject(url, request, JwtResponse.class);
System.out.println(res);
*/
localApiClient
.post()
.uri(url)
.body(Mono.just(loginRequest), LoginRequest.class)
.retrieve()
.bodyToMono(JwtResponse.class)
.block();
}
private String getBaseUrl(String serviceName) {
Application application = eurekaClient.getApplication(serviceName);
InstanceInfo instanceInfo = application.getInstances().get(0);
String hostname = instanceInfo.getHostName();
int port = instanceInfo.getPort();
return "http://" + hostname + ":" + port;
}
application.yml:
server.port: 9903
spring:
application.name: bbsim-manager-service
eureka:
client:
serviceUrl:
defaultZone: ${EUREKA_URI:http://localhost:8088/eureka}
registryFetchIntervalSeconds: 1
# register-with-eureka: true
# fetch-registry: true
instance:
leaseRenewalIntervalInSeconds: 1
If I understand well, the request does not reach the login service at all.
Login (called) service:
#PostMapping("/signin")
public ResponseEntity<?> authenticateUser(#Valid #RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtUtils.generateJwtToken(authentication);
UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
List<String> roles = userDetails.getAuthorities().stream()
.map(item -> item.getAuthority())
.collect(Collectors.toList());
return ResponseEntity.ok().body(new JwtResponse(jwt,
userDetails.getId(),
userDetails.getUsername(),
userDetails.getEmail(),
roles));
}
application.yml file:
server.port: 9902
spring:
application:
name: bbsim-login-service
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8088/eureka/
registryFetchIntervalSeconds: 1
instance:
leaseRenewalIntervalInSeconds: 1
I addition, I tried the following - giving me the same results:
curl -d "#data.json" -H "Content-Type: application/json" -X POST http://localhost:9903/login
where data.json has the body contents.
This will not be a complete answer but I hope it helps you with your issue.
I think your problem could be related with a mix of the different IP address of your machine.
First, I think Eureka is exposing your services like host.docker.internal, as indicated, the logical name that references the host machine through the different docker containers, for the reason explained in this SO question.
Basically, it seems that the docker software is updating your hosts file with entries for host.docker.internal and gateway.docker.internal and Eureka probably is taking that alias as the one for the machine IP that is being advertised. Please, see the accepted answer in the aforementioned question.
When you run Spring Boot normally the underlying server (Tomcat, Jetty, Undertow) will listen for connections in the 0.0.0.0 address, i.e., in all the network interfaces available, including localhost. This is what troubles me, because as indicated, the service should be accessible through all the IPs in the machine.
In any way, I think you can try several things to solve your issue.
Probably the best approach to solve the problem will be to configure the hostname of your Eureka server and/or your Eureka clients to a common one.
For example, you can configure your server and clients to be exposed as localhost.
For that purpose, you need to include the following configuration property in their respective config files:
eureka:
instance:
hostname: localhost
Looks like you are using Docker. You are trying to connect to localhost but other services are running in other container hence localhost won’t work. Would you please try 0.0.0.0 or host.docker.internal in your YAML file and see if that will work.
In other words you will need to edit following.
server.port: 9903
spring:
application.name: bbsim-manager-service
eureka:
client:
serviceUrl:
defaultZone: ${EUREKA_URI:http://host.docker.internal:8088/eureka}
registryFetchIntervalSeconds: 1
# register-with-eureka: true
# fetch-registry: true
instance:
leaseRenewalIntervalInSeconds: 1
or change EUREKA_URI env variable to reflect that. Also in your service YAML
server.port: 9902
spring:
application:
name: bbsim-login-service
eureka:
client:
serviceUrl:
defaultZone: ${EUREKA_URI:http://host.docker.internal:8088/eureka/}
registryFetchIntervalSeconds: 1
instance:
leaseRenewalIntervalInSeconds: 1

Spring Email: Must issue a STARTTLS command first

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

I am unable to configure email with my application i have created a separate email utility but following error is occurring

I am trying to connect gmail server and want to send email to same account for learning purpose but it is throwing this exception.
#Service
public class EmailUtilImpl implements EmailUtil {
#Autowired
private JavaMailSender sender;
#Override
public void sendEmail(String toAddress, String subject, String body)
{
MimeMessage message= sender.createMimeMessage();
MimeMessageHelper helper= new MimeMessageHelper(message);
try {
helper.setTo(toAddress);
helper.setSubject(subject);
helper.setText(body);
}
catch(MessagingException e)
{
e.printStackTrace();
}
sender.send(message);
}
}
spring.mail.host = smtp.gmail.com
spring.mail.port = 587
spring.mail.username = myemail
spring.mail.password = mypassword
spring.mail.properties.mail.smtp.starttls.enable= true
spring.mail.properties.mail.smtp.starttls.required = true # Other properties
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.writetimeout=5000
Error:
There was an unexpected error (type=Internal Server Error,
status=500). Mail server connection failed; nested exception is
com.sun.mail.util.MailConnectException: Couldn't connect to host,
port: smtp.gmail.com, 587; timeout -1; nested exception is:
java.net.SocketException: Permission denied: connect. Failed messages:
com.sun.mail.util.MailConnectException: Couldn't connect to host,
port: smtp.gmail.com, 587; timeout -1; nested exception is:
java.net.SocketException: Permission denied: connect
Try with below property
spring:
mail:
host: smtp.gmail.com
port: 587
username: <YOUR_EMAIL_ADDRESS>
password: <YOUR_EMAIL_PASSWORD>
properties:
mail:
smtp:
starttls:
enable: true
required: true
auth: true
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username= yourAccount#gmail.com
spring.mail.password= generated App Password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
Generate App Password
Other Possible Solutions
Change Port to 465
Disable your firewall/antivirus and run again
Add java.net.preferIPv4Stack in the main application
System.setProperty("java.net.preferIPv4Stack", "true")

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