You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

二、配置修改步骤

  1. 更新依赖
    确保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
  2. 替换邮件配置
    去掉静态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
    
  3. 自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 02:07:34