Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
andreas-eberle opened this issue Mar 12, 2024 Discussed in #38773 · 13 comments
Open

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

andreas-eberle opened this issue Mar 12, 2024 Discussed in #38773 · 13 comments

Comments

@andreas-eberle
Copy link
Contributor

Discussed in #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
Copy link

quarkus-bot bot commented Mar 12, 2024

/cc @cescoffier (mailer)

@sberyozkin
Copy link
Member

sberyozkin commented Mar 12, 2024

If the Instance<TokenCredential> suggestion can be considered reasonable (#38773 (reply in thread)) 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
Copy link
Member

gsmet commented Aug 12, 2024

@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
Copy link
Contributor Author

Yes, exactly we want to do the former.

@wernerjacobs
Copy link

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

@cescoffier
Copy link
Member

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
Copy link
Member

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
Copy link
Member

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
Copy link
Member

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
Copy link

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
Copy link
Member

@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
Copy link
Contributor Author

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
Copy link
Member

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:

  • the mailer must use a different connection pool in this case, as each would use a different authentication. We could imagine a mode where we instantiate a mailer for every "send", but it would be very slow as the connection would need to be re-established (while authentication is just a command). There might be a way to recycle previous connections, but it needs to be investigated
  • If the previous point works, we need to change how we pass authentication data to produce the token on every send (the token could be cached).

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants