quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.84k stars 2.7k forks source link

XOauth2 support for Quarkus Mailer e.g. for Office365 #39359

Open andreas-eberle opened 8 months ago

andreas-eberle commented 8 months ago

Discussed in https://github.com/quarkusio/quarkus/discussions/38773

Office365 by default required XOauth2 authorization. This is currently not supported by the Quarkus Mailer integration. Therefore, this makes it really hard to use Quarkus mailing with Microsoft E-Mail accounts.

Originally posted by **wernerjacobs** February 14, 2024 Hello, We're currently working on integrating Quarkus mail with our application and need to authenticate to smtp.office365.com using OAuth. Unfortunately, the documentation doesn't provide specific guidance on configuring Office 365 mail. We've attempted to replicate configurations used for other mail servers, but so far, we haven't had much success. Currently, we're encountering an SSL handshake issue and are unable to proceed. Our firewall settings should allow communication with smtp.office365.com on port 587, so we don't believe that's the source of the problem. However, when attempting to send a message, we're seeing the following error in our logs: Caused by: io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record: [error message] at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1314) Has anyone encountered similar challenges with configuring mail for Office 365 mail servers? We've verified that the protocols and cipher suites are correctly configured, so we're unsure what else could be causing this error. Does anybody know which configuration properties should be set? We are setting following properties quarkus.mailer.auth-methods=DIGEST-MD5 CRAM-SHA256 CRAM-SHA1 CRAM-MD5 PLAIN LOGIN quarkus.mailer.start-tls=REQUIRED quarkus.mailer.from=XXXX quarkus.mailer.host=smtp.office365.com quarkus.mailer.port=587 quarkus.mailer.username=XXX quarkus.mailer.password=XXXX quarkus.mailer.ssl=true quarkus.mailer.login=XOAUTH2 quarkus.mailer.trust-all=true Any insights or assistance would be greatly appreciated. Thank you
quarkus-bot[bot] commented 8 months ago

/cc @cescoffier (mailer)

sberyozkin commented 8 months ago

If the Instance<TokenCredential> suggestion can be considered reasonable (https://github.com/quarkusio/quarkus/discussions/38773#discussioncomment-8515842) then I can prototype some code in a draft PR.

The case of a Quarkus endpoint authenticating the users with the authorization code flow and then propagating the token to access some downstream service is generic - which is why I'm not sure that having the mailer specific OAuth2 support is the best approach

gsmet commented 3 months ago

@andreas-eberle can you clarify your use case? You want to send system emails with a generic user or you actually want to send emails on behalf of a connected user?

I was thinking you wanted to do the former but I prefer asking.

andreas-eberle commented 3 months ago

Yes, exactly we want to do the former.

wernerjacobs commented 3 months ago

Any progress on this one ?is it impossible or not desired?

cescoffier commented 3 months ago

It should be possible. The question is how to get the token. We cannot sure Quarkus OIDC for this (at least not directly). We would need some custom code to retrieve the token and refresh it, before configuring the mailer. I'm a bit worried but the refreshing part as it would probably mean that the mailer must be re-created (we may have inflight emails).

sberyozkin commented 3 months ago

Hey @andreas-eberle, @wernerjacobs,

We are looking into it. Can you clarify please, what exactly does Office 365 recommend users to get configured on the client side to get XOAuth2 working for the system email case ?

Is it a generic user's name and password or you already have a token generated somewhere in the Office or EntraID dashboard and have to copy it to the client configuration, to have the generic user's name and this already prepared token configured ?

FYI, since we are talking about the system email with the generic user case, the understanding is that no user login to Entra ID is expected for the mailer be able to use XOUTH2 protocol...

Please clarify further. Also, can you set up a test account in Entra ID and/or Office 365 by any chance to make it easier for us to test the upcoming fix ?

Thanks

cescoffier commented 3 months ago

Sergey and I just discussed it.

Sergey is going to start a proof of concept to clarify how we can retrieve a token with Google and Office 365 (so we are sure we do not introduce provider-specific behavior). Once we know how to do that, integrating it into the Quarkus mailer is simple. It will require a bit of refactoring, but it will be very localized and easy to achieve.

That said, it cannot be included in the next LTS version of Quarkus (3.15) as we are after the feature freeze. We are confident that it should be delivered by the late 2024-beginning 2025.

sberyozkin commented 3 months ago

Hi @andreas-eberle @wernerjacobs

I've been rereading this issue description.

Do you see any specific docs, confirmations in the Microsoft community, that using (X)OAuth2 works for the generic user/system email case, where no user login is required, where either OIDC client credentials or password or jwt bearer grant is used to acquire a token for the XOAuth2 authentication to succeed ? Please share whatever info you may have, thanks

wernerjacobs commented 3 months ago

Hey @andreas-eberle, @wernerjacobs,

We are looking into it. Can you clarify please, what exactly does Office 365 recommend users to get configured on the client side to get XOAuth2 working for the system email case ?

Is it a generic user's name and password or you already have a token generated somewhere in the Office or EntraID dashboard and have to copy it to the client configuration, to have the generic user's name and this already prepared token configured ?

FYI, since we are talking about the system email with the generic user case, the understanding is that no user login to Entra ID is expected for the mailer be able to use XOUTH2 protocol...

Please clarify further. Also, can you set up a test account in Entra ID and/or Office 365 by any chance to make it easier for us to test the upcoming fix ?

Thanks

Hi Sergey,

I am on holidays for the moment with limited access to my company resources. I remember that I received a user and some secret to obtain the token but it will always be the same user. I need to recontact my office 365 administrator to obtain more details about which methods are used and if there is more documentation, so we can provide it to you.

Already big thanks to taking this up, probably I will come back to you as late as second week of september as I will be back to work and obtain the necessary info.

sberyozkin commented 3 months ago

@wernerjacobs Hi, sounds good, thanks for the update so far, please get back to us with more info when you get it.

I think we are talking about the OIDC client credentials grant here, but the more info we can get the better... Cheers

andreas-eberle commented 2 months ago

Unfortunately, that project for which I initially requested this has ended (we ended up using a different mail provider). So I currently do not have access to a test setup and don't remember the details. Thanks @wernerjacobs for helping out!

cescoffier commented 2 weeks ago

The underlying mailer handles OAuth2; however, the client must be instantiated with the username (the application ID) and the password (the token). This means it does not handle token refresh, and once the mailer has the authentication data, it does not change.

Based on the current assumptions, there are two main consequences:

We are still waiting for details about how Office 365 handles authentication. Depending on this, our assumptions may be wrong. For example, the token may be perpetual (does not expire), which would simplify the issue a lot.

wernerjacobs commented 1 week ago

Sorry for the late return, in the meantime, we ran into some limitations about using our Office365 server for bulk e-mail sending. There are some limits our department can not live with.

Our platform team has decided to start using Azure Communication Services instead. This requires an Azure managed Identity, we already have similar cases where we use an managed identity to connect to Azure Blob storages. So the connection will no longer be a problem as we do not need to authenticate anylonger to a smtp server with XOAUTH2 but using Azure Java SDK library.

Apart from this change (Office 365 to Azure Communication Services), I did not get more information about how Office 365 handles connections.

I know this was/is not really helpful, but I want to thank you for taking your time to investigate this issue.