如何将Spring Boot邮件发送功能从SMTP升级至OAuth认证
问题:Spring Boot应用切换Office 365 SMTP到OAuth2发送邮件
我为公司设计并部署了一款Spring Boot Web应用,用户填写在线表单后点击“发送”按钮,通过Office 365的SMTP向指定收件人发送邮件。但获悉自2025年9月25日起,微软将要求使用OAuth进行邮件发送连接,替代原有的smtp.office365.com方式。
我已做了大量研究和尝试,仍未找到可行方案。希望有人提供修改步骤或相关见解。
以下是当前的配置信息:
spring.mail.transport.protocol=smtp spring.mail.host=smtp.office365.com spring.mail.port=587 spring.mail.username=application_name@company.org # Use the OAuth2 access token here spring.mail.properties.mail.smtp.sasl.enable=true spring.mail.properties.mail.smtp.sasl.mechanisms=XOAUTH2 spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true # This is the authorization token you will get from the OAuth flow (OAuth2 token): spring.mail.properties.mail.smtp.auth.token=YOUR_ACCESS_TOKEN
另外,基于SMTP实现的EmailService代码如下,想问切换到OAuth是否需要修改该服务?
@Service public class EmailServiceImpl implements EmailService { @Autowired private JavaMailSender emailSender; @Async @Override public void send(Map<String, File> fileMap, List<String> to) throws MessagingException { MimeMessage message = emailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setFrom("application_name@company.org"); helper.setTo(to.toArray(new String[0])); Set<String> keySet = fileMap.keySet(); for (String filename : keySet) { File file = fileMap.get(filename); if (file.exists()) { FileSystemResource fileSystemResource = new FileSystemResource(file); // Add logging to check the file information System.out.println("Attaching file: " + filename); helper.addAttachment(filename, fileSystemResource); } } helper.setText( "<b>DO NOT REPLY</b><br>" + "confirmation email message typed here", true); helper.setSubject("Application Received - Thank you for your Interest."); emailSender.send(message); } }
解决方案
一、前置准备
首先要在Azure AD中完成应用注册:
- 创建新的企业应用,获取客户端ID和客户端密钥
- 配置应用权限:添加
SMTP.Send的应用权限(注意是应用权限,不是委派权限,因为服务是后台自动发送,无用户交互),并让管理员同意该权限 - 记录你的Azure AD租户ID
二、配置修改步骤
更新依赖
确保Spring Boot版本≥2.7,添加OAuth2相关依赖:- Spring Boot 3.x:
spring-boot-starter-oauth2-client、spring-boot-starter-oauth2-resource-server - Spring Boot 2.x:
spring-security-oauth2-client、spring-security-oauth2-jose
- Spring Boot 3.x:
替换邮件配置
去掉静态token配置,新增OAuth2客户端配置:spring.mail.transport.protocol=smtp spring.mail.host=smtp.office365.com spring.mail.port=587 spring.mail.username=application_name@company.org spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true spring.mail.properties.mail.smtp.sasl.enable=true spring.mail.properties.mail.smtp.sasl.mechanisms=XOAUTH2 # OAuth2 客户端配置 spring.security.oauth2.client.registration.azure.client-id=你的Azure客户端ID spring.security.oauth2.client.registration.azure.client-secret=你的Azure客户端密钥 spring.security.oauth2.client.registration.azure.authorization-grant-type=client_credentials spring.security.oauth2.client.provider.azure.token-uri=https://login.microsoftonline.com/你的租户ID/oauth2/v2.0/token spring.security.oauth2.client.registration.azure.scopes=https://outlook.office365.com/SMTP.Send自定义JavaMailSender配置
创建配置类,让邮件客户端自动获取并注入OAuth2 token:@Configuration public class MailConfig { @Autowired private OAuth2AuthorizedClientService authorizedClientService; @Autowired private ClientRegistrationRepository clientRegistrationRepository; @Bean public JavaMailSender javaMailSender() { JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); mailSender.setHost("smtp.office365.com"); mailSender.setPort(587); mailSender.setUsername("application_name@company.org"); mailSender.setPassword(null); // 无需密码,用OAuth2 token替代 Properties props = mailSender.getJavaMailProperties(); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.starttls.required", "true"); props.put("mail.smtp.sasl.enable", "true"); props.put("mail.smtp.sasl.mechanisms", "XOAUTH2"); mailSender.setSession(getOAuth2MailSession()); return mailSender; } private Session getOAuth2MailSession() { return Session.getInstance(mailSender.getJavaMailProperties(), new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { // 获取client_credentials模式的token ClientRegistration registration = clientRegistrationRepository.findByRegistrationId("azure"); OAuth2AuthorizedClient client = authorizedClientService.loadAuthorizedClient( registration.getRegistrationId(), OAuth2AuthenticationPrincipal.ANONYMOUS_PRINCIPAL_NAME ); String accessToken = client.getAccessToken().getTokenValue(); return new PasswordAuthentication("application_name@company.org", accessToken); } }); } }
三、EmailService是否需要修改?
不需要。你的EmailServiceImpl核心逻辑只是调用JavaMailSender发送邮件,只要JavaMailSender配置正确,能处理OAuth2认证,服务层代码可以完全保持原样。唯一要注意的是setFrom的邮箱要和Azure AD中配置的权限对应邮箱一致,确保该邮箱拥有发送权限。
四、额外注意事项
- 确保Azure AD应用的
SMTP.Send权限已获得管理员同意 - 可开启邮件会话debug模式(
session.setDebug(true)),查看SMTP交互日志排查问题 - Spring Security OAuth2客户端会自动处理token的获取和过期刷新,无需手动维护
内容的提问来源于stack exchange,提问作者ChloeCheerUp
相关产品推荐
相关产品推荐

