SMTP Microsoft 365: enviar e‑mails via smtp.office365.com (OAuth 2.0, Graph e alternativas)

Resumo prático: quer enviar e‑mails a partir de uma aplicação usando o Microsoft 365? A forma suportada e segura é a submissão SMTP autenticada em smtp.office365.com (porta 587, STARTTLS) com uma mailbox licenciada e autenticação moderna (OAuth 2.0). Se não quiser licenças, use um conector de SMTP relay ou a API Microsoft Graph. Abaixo explico o “como” e o “porquê”, com passos concretos, comandos e exemplos de código.

Índice

Visão geral do problema

O autor está a configurar SMTP client submission para uma aplicação e quer saber se pode usar uma conta sem licença no Microsoft 365. Também pergunta se vale a pena recorrer a serviços externos (SendGrid, SMTPget) em vez do próprio Microsoft 365.

Resposta curta e direta

  • Para autenticar via smtp.office365.com é necessário uma caixa de correio licenciada (Exchange Online). Sem licença, a submissão autenticada é bloqueada.
  • Use SMTP AUTH com OAuth 2.0. A autenticação básica (user/senha) está bloqueada por políticas modernas e tem end-of-life anunciado; a recomendação é migrar para OAuth 2.0.
  • Alternativas sem licença: conector de SMTP relay (porta 25 com TLS e IP/certificado confiável), Microsoft Graph (/sendMail) ou provedores externos (SendGrid, etc.).

Tabela-resumo da solução

EtapaDetalhes práticos
Atribua uma licença de Exchange OnlinePara autenticar-se via smtp.office365.com (porta 587, STARTTLS), a mailbox precisa estar licenciada. Sem licença, a submissão SMTP é recusada.
Use SMTP AUTH com OAuth 2.0SMTP AUTH continua disponível, porém a Autenticação Básica está bloqueada em muitos tenants e com retirada anunciada. Se vir “Authentication unsuccessful, basic authentication is disabled”, migre para OAuth 2.0 (autenticação moderna) ou ajuste as políticas — a prática recomendada é OAuth.
Configuração mínimaServidor: smtp.office365.com • Porta: 587STARTTLS obrigatório (TLS 1.2+) • Credenciais OAuth 2.0 (token) ou credenciais da caixa licenciada, conforme sua política.
Alternativas externasSendGrid / SMTPget dispensam licenças do Microsoft 365 e simplificam tokens, porém: implicam custo, saem do guarda‑chuva de segurança/compliance da Microsoft e exigem ajuste de SPF/DKIM/DMARC.
Outras opções de envioMicrosoft Graph (/sendMail) para envio via REST com application permissions (sem SMTP). Conector autenticado no Exchange Online para dispositivos multifuncionais e servidores locais.

Decisão rápida: qual caminho escolher?

CenárioSugestãoObservações
Aplicação moderna (pode guardar client secret ou certificado)SMTP AUTH + OAuth 2.0 (App‑only)Sem interação de usuário; use permissão application e service principal em Exchange.
Aplicação que já fala HTTP/RESTMicrosoft Graph /sendMailEntrega confiável, controles finos de acesso; não é SMTP.
Dispositivo/MFP sem suporte a OAuthSMTP relay com conectorRequer IP fixo ou certificado e porta 25; não exige licença de mailbox.
Precisa reduzir esforço operacionalSendGrid/SMTPgetMenos fricção técnica, mas custo e menor integração de compliance.

SMTP AUTH com OAuth 2.0 (App‑only) — passo a passo

Este fluxo não envolve login interativo e é ideal para serviços/backend. A aplicação obtém um token via client credentials e autentica no SMTP com XOAUTH2.

  1. Registe a aplicação no Microsoft Entra ID (antigo Azure AD).
  2. Permissões: em API permissions, adicione a API Office 365 Exchange OnlineApplication permissionsSMTP.SendAsApp. (Se for usar IMAP/POP, adicione IMAP.AccessAsApp/POP.AccessAsApp.)
  3. Dê consentimento de administrador para as permissões application.
  4. Registe o Service Principal no Exchange Online (PowerShell): Install-Module ExchangeOnlineManagement -Scope CurrentUser Connect-ExchangeOnline New-ServicePrincipal -AppId <APPLICATIONID> -ObjectId <OBJECTID>
  5. Permita o acesso às mailboxes:
    • FullAccess (leitura/gravação de pasta): Add-MailboxPermission -Identity user@contoso.com -User <SERVICEPRINCIPALID> -AccessRights FullAccess
    • Send As (enviar como a mailbox): Add-RecipientPermission -Identity user@contoso.com -Trustee <SERVICEPRINCIPALID> -AccessRights SendAs
  6. Obtenha o token com client credentials usando o scope https://outlook.office365.com/.default (ou “resource” equivalente).
  7. Autentique no SMTP em smtp.office365.com:587 com STARTTLS e SASL XOAUTH2.

Exemplo (Python 3 + MSAL + smtplib)

import base64, smtplib
from msal import ConfidentialClientApplication

tenant\id = "SEU\TENANT\_ID"
client\id = "SEU\CLIENT\_ID"
client\secret = "SEU\CLIENT\_SECRET"
username = "[remetente@contoso.com](mailto:remetente@contoso.com)"  # endereço que terá Send As

app = ConfidentialClientApplication(
client\id=client\id,
authority=f"[https://login.microsoftonline.com/{tenant\id}](https://login.microsoftonline.com/{tenantid})",
client\credential=client\secret
)

result = app.acquire\token\for\_client(scopes=\["[https://outlook.office365.com/.default](https://outlook.office365.com/.default)"])
access\token = result\["access\token"]

def xoauth2(user, token):
auth\_string = f"user={user}\x01auth=Bearer {token}\x01\x01"
return base64.b64encode(auth\_string.encode()).decode()

with smtplib.SMTP("smtp.office365.com", 587) as smtp:
smtp.ehlo()
smtp.starttls()  # TLS 1.2 ou superior
smtp.ehlo()
smtp.docmd("AUTH", "XOAUTH2 " + xoauth2(username, access\_token))
from\_addr = username
to\_addrs = \["[destino@exemplo.com](mailto:destino@exemplo.com)"]
msg = ("Subject: Teste SMTP OAuth2\r\n"
f"From: {from\addr}\r\nTo: {', '.join(to\addrs)}\r\n\r\n"
"Mensagem enviada com token OAuth2.\r\n")
smtp.sendmail(from\addr, to\addrs, msg)

Exemplo (C# + MailKit)

using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
using Microsoft.Identity.Client;

var tenantId = "SEU\TENANT\ID";
var clientId = "SEU\CLIENT\ID";
var clientSecret = "SEU\CLIENT\SECRET";
var authority = \$"[https://login.microsoftonline.com/{tenantId}](https://login.microsoftonline.com/{tenantId})";

IConfidentialClientApplication app = ConfidentialClientApplicationBuilder
.Create(clientId).WithAuthority(authority).WithClientSecret(clientSecret).Build();

var token = await app.AcquireTokenForClient(
new\[] { "[https://outlook.office365.com/.default](https://outlook.office365.com/.default)" }).ExecuteAsync();

using var smtp = new SmtpClient();
await smtp.ConnectAsync("smtp.office365.com", 587, SecureSocketOptions.StartTls);
var oauth2 = new SaslMechanismOAuth2("[remetente@contoso.com](mailto:remetente@contoso.com)", token.AccessToken);
await smtp.AuthenticateAsync(oauth2);

var message = new MimeMessage();
message.From.Add(MailboxAddress.Parse("[remetente@contoso.com](mailto:remetente@contoso.com)"));
message.To.Add(MailboxAddress.Parse("[destino@exemplo.com](mailto:destino@exemplo.com)"));
message.Subject = "Teste SMTP OAuth";
message.Body = new TextPart("plain") { Text = "Olá!" };

await smtp.SendAsync(message);
await smtp.DisconnectAsync(true);

Exemplo (Node.js + MSAL + Nodemailer)

const { ConfidentialClientApplication } = require("@azure/msal-node");
const nodemailer = require("nodemailer");

const tenantId = "SEU\TENANT\ID";
const clientId = "SEU\CLIENT\ID";
const clientSecret = "SEU\CLIENT\SECRET";
const authority = `https://login.microsoftonline.com/${tenantId}`;

const cca = new ConfidentialClientApplication({
auth: { clientId, authority, clientSecret }
});

async function getToken() {
const res = await cca.acquireTokenByClientCredential({
scopes: \["[https://outlook.office365.com/.default](https://outlook.office365.com/.default)"]
});
return res.accessToken;
}

(async () => {
const accessToken = await getToken();
const transporter = nodemailer.createTransport({
host: "smtp.office365.com",
port: 587,
secure: false,
auth: { type: "OAuth2", user: "[remetente@contoso.com](mailto:remetente@contoso.com)", accessToken },
tls: { ciphers: "TLSv1.2" }
});

await transporter.sendMail({
from: "[remetente@contoso.com](mailto:remetente@contoso.com)",
to: "[destino@exemplo.com](mailto:destino@exemplo.com)",
subject: "Teste SMTP OAuth2",
text: "Corpo do e-mail"
});
})();

SMTP AUTH com OAuth 2.0 (delegated)

Se a aplicação “age como um usuário”, use authorization code ou device code para obter o token com o scope https://outlook.office365.com/SMTP.Send e, opcionalmente, offline_access para refresh tokens. O cabeçalho XOAUTH2 é o mesmo; muda apenas a forma de obter o token.

Ativar/validar o SMTP AUTH no tenant e na mailbox

  • Nível organização: garanta que o SMTP AUTH não está desativado globalmente.
  • Nível mailbox: desative apenas nas caixas que não precisam e habilite nas que irão enviar.
# Organização (desliga o bloqueio global do SMTP AUTH)
Set-TransportConfig -SmtpClientAuthenticationDisabled $false

Mailbox específica

Set-CASMailbox -Identity [remetente@contoso.com](mailto:remetente@contoso.com) -SmtpClientAuthenticationDisabled \$false

Importante: Security Defaults no Entra ID bloqueiam autenticação básica em protocolos legados; a orientação atual é usar OAuth 2.0. Portas suportadas: 587 (recomendado) com STARTTLS; a porta 465 (implicit TLS) não é suportada para cliente SMTP no Exchange Online.

Configuração mínima recomendada

  • Servidor: smtp.office365.com
  • Porta: 587
  • Criptografia: STARTTLS (TLS 1.2 ou 1.3)
  • Autenticação: OAuth 2.0 (XOAUTH2) com scope https://outlook.office365.com/.default para app‑only, ou https://outlook.office365.com/SMTP.Send para delegated.
  • Mailbox: licenciada (Exchange Online). Para enviar “como” outra caixa (ex.: shared mailbox), conceda Send As à entidade que se autentica.

Alternativas sem licenças de mailbox

Conector de SMTP relay (Exchange Online)

Crie um conector autenticado por certificado ou IP fixo e aponte o dispositivo/servidor para o smart host do seu MX (<dominio>-com.mail.protection.outlook.com) na porta 25 com TLS. Vantagens: não exige mailbox, tem limites mais altos e permite enviar usando endereços do seu domínio. Limitações: requer IP/certificado confiável e não funciona a partir de hospedagens de terceiros sem configuração especial.

Microsoft Graph (/sendMail)

Para aplicações HTTP, enviar por Graph é simples, seguro e não depende de SMTP. Configure application permission Mail.Send, dê admin consent e (opcional) restrinja a app a um conjunto de caixas com Application Access Policy.

# Exemplo: envio com Microsoft Graph (app-only)
import requests
from msal import ConfidentialClientApplication

tenant = "SEU\TENANT\ID"; client = "SEU\CLIENT\ID"; secret = "SEU\CLIENT\SECRET"
app = ConfidentialClientApplication(client, authority=f"[https://login.microsoftonline.com/{tenant}](https://login.microsoftonline.com/{tenant})", client\_credential=secret)
token = app.acquire\token\for\client(scopes=\["[https://graph.microsoft.com/.default"\])\["access\token](https://graph.microsoft.com/.default%22]%29[%22access_token)"]

payload = {
"message": {
"subject": "Teste Graph",
"body": { "contentType": "Text", "content": "Olá do Graph!" },
"toRecipients": \[{ "emailAddress": { "address": "[destino@exemplo.com](mailto:destino@exemplo.com)" } }]
}
}
resp = requests.post("[https://graph.microsoft.com/v1.0/users/remetente@contoso.com/sendMail](https://graph.microsoft.com/v1.0/users/remetente@contoso.com/sendMail)",
headers={"Authorization": f"Bearer {token}"}, json=payload)
resp.raise\for\status()

Provedores externos (SendGrid, SMTPget): prós e contras

CritérioMicrosoft 365 (nativo)SendGrid / SMTPget
Segurança e complianceHerda políticas do Entra ID, DLP, auditoria, eDiscovery, message trace.Fora do ecossistema Microsoft; requer acordos e avaliações de risco.
Reputação de domínioEnvia “pelo seu” domínio com SPF/DKIM/DMARC do M365.Boa entregabilidade, mas precisa configurar sender domain e autenticação dedicada.
CustoSem custo adicional além da licença/excedentes.Plano mensal/por volume; pode baratear em alto volume.
Complexidade técnicaMais ajustes iniciais (OAuth, permissões, conector).SDKs prontos; pouca fricção para começar.
GovernançaRBAC centralizado, políticas por mailbox.Gestão paralela (chaves, políticas) fora do M365.

Autenticação de domínio: SPF, DKIM e DMARC

  • SPF: inclua include:spf.protection.outlook.com (e o do seu provedor externo, se usar). Ex.: v=spf1 include:spf.protection.outlook.com -all
  • DKIM: ative a assinatura DKIM para o seu domínio no centro de administração do Exchange.
  • DMARC: publique v=DMARC1; p=quarantine; rua=mailto:dmarc@contoso.com (ajuste a política consoante sua maturidade).

Limites e boas práticas de envio

  • Client submission: típicos 10.000 destinatários/dia e 30 mensagens/minuto por mailbox.
  • Proteções anti‑abuso: o serviço limita picos e padrões suspeitos. Planeie retry exponencial.
  • Idempotência: gere Message‑ID e controle duplicidades.
  • Observabilidade: use message trace, mail flow reports e logs da aplicação.

Erros comuns e como corrigir

ErroCausa provávelCorreção
535 5.7.3 Authentication unsuccessfulToken inválido/expirado, permissão insuficiente, SMTP AUTH desabilitado.Renove o token; valide SMTP.SendAsApp ou SMTP.Send; verifique SmtpClientAuthenticationDisabled.
5.7.60 Client doesn't have permissions to send as this senderFalta de Send As na mailbox alvo.Conceda Send As ao service principal (Add-RecipientPermission).
5.7.57 Client was not authenticated to send anonymous mailA tentar enviar sem autenticação na porta 25 (Direct Send).Use client submission (porta 587) com autenticação ou configure SMTP relay com conector.
StartTLS is required / TLS versionConexão sem TLS ou com TLS < 1.2.Habilite STARTTLS e TLS 1.2+; nunca use porta 465.
basic authentication is disabledPolíticas modernas bloqueiam básico; retirada anunciada.Migre para OAuth 2.0 (delegated ou app‑only) ou ajuste temporariamente as políticas (não recomendado).

FAQ objetivo

Posso usar uma conta sem licença para SMTP client submission? Não. Client submission exige uma mailbox licenciada. Alternativas: SMTP relay com conector (sem mailbox) ou Graph.

Posso enviar de uma shared mailbox sem licenciá‑la? Sim, desde que autentique com uma conta licenciada e conceda Send As para a shared. Para app‑only, conceda permissões ao service principal.

Vale a pena usar SendGrid/SMTPget? Se quer começar rápido ou enviar alto volume de notificações, pode valer. Se governança/compliance do Microsoft 365 é prioridade e o volume é moderado, prefira o nativo.

Quando usar Graph em vez de SMTP? Sempre que possível: simplifica tokens, evita limitações de SMTP, dá controlo de escopo por política e melhora a rastreabilidade.

Checklist final de implementação

  1. Defina arquitetura: SMTP OAuth (delegated/app‑only), Graph ou SMTP relay.
  2. Se SMTP OAuth:
    • Registe a app, adicione SMTP.SendAsApp/SMTP.Send, dê admin consent.
    • Registe o service principal no Exchange e conceda Send As/FullAccess às mailboxes.
    • Implemente o fluxo de token (client credentials ou authorization code).
    • Conecte em smtp.office365.com:587 com STARTTLS e XOAUTH2.
  3. Se Graph: adicione Mail.Send, aplique Application Access Policy, implemente /sendMail.
  4. Se relay: configure conector (IP/certificado), aponte para o MX e use porta 25 com TLS.
  5. Ative DKIM, publique SPF/DMARC e teste a entregabilidade.
  6. Monitore message trace, limites e falhas 4xx/5xx com retry/backoff.

Resumo em uma linha: Para enviar e‑mails por SMTP através do Microsoft 365 é obrigatório ter uma caixa de correio licenciada (no modo client submission) e, com a saída da Autenticação Básica, usar SMTP AUTH com OAuth 2.0 ou outra forma de autenticação moderna; provedores externos como SendGrid são viáveis, mas perdem os benefícios de segurança e conformidade integrados ao Microsoft 365.


Dicas rápidas de SEO e redação

  • Inclua “SMTP Microsoft 365”, “OAuth 2.0”, “smtp.office365.com” e “Graph API” no corpo e subtítulos.
  • Mantenha trechos práticos (códigos, comandos e tabelas) — melhoram o tempo na página e backlinks naturais.
  • Adicione perguntas com linguagem natural (FAQ) para capturar featured snippets.
Índice