Skip to content

IMAP with OAuth 2 authentication #341

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

Closed
dmitryallen opened this issue Jan 18, 2023 · 8 comments
Closed

IMAP with OAuth 2 authentication #341

dmitryallen opened this issue Jan 18, 2023 · 8 comments

Comments

@dmitryallen
Copy link

Hello,
is there possibility to get sample IMAP integration with OAuth 2 authentication ?

@garyrussell
Copy link
Contributor

See https://javaee.github.io/javamail/OAuth2

It looks like this needs a change in AbstractMailReceiver in the main project, to pass the token into the connect() method.

@artembilan
Copy link
Member

artembilan commented Jan 18, 2023

Why is the question for Spring Integration, but not directly to Java Mail API, where that OAuth 2 authentication resides?
Spring Integration does nothing special in this area unless exposes an AbstractMailReceiver.javaMailAuthenticator option where we indeed should implement any possible dynamic authentication mechanism.
That Authenticator.getPasswordAuthentication() implementation should get the current user calling getDefaultUserName().
Then you perform your API to obtain an OAuth token and return new PasswordAuthentication with both of them.

@dmitryallen
Copy link
Author

Thanks Garry and Artem,
I'm just looking for sample code with Mail Integration using OAuth 2 and I could not find any working code.
Looks like in near future OAuth 2 will be the main method to authenticate mailboxes in automation tasks.
Microsoft is deprecating old password authentication in Azure.
https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/deprecation-of-basic-authentication-exchange-online
https://techcommunity.microsoft.com/t5/exchange-team-blog/basic-authentication-deprecation-in-exchange-online-time-s-up/ba-p/3695312

Artem, this repository is [spring-integration-samples], so authentication related question can be relevant here.
I thought that you already have sample code for mail integration with OAuth 2 or working on it.

Thanks
Dmitry

@artembilan
Copy link
Member

Well, this repository is for samples based on Spring Integration solutions: https://spring.io/projects/spring-integration.
Mostly about channel adapters to this or that system.
We demonstrate here components from this framework and how they work together.
Spring Integration does not owe OAuth for email API. That is native Java Mail feature.

We will be glad to add something OAuth-based into existing mail samples, but for that purpose we need to learn more and will be glad to accept any contributions on the matter.
Although if I would search this feature I'd go first to Java Mail project.

To be more specific: what is your take on that jakarta.mail.Authenticator API?

@dmitryallen
Copy link
Author

Thanks Artem,
it's clear about Authenticator, I can initialize JavaMailSenderImpl with OAuth and implement renew of session.
There is not possibility to set mail-sender in inbound-channel-adapter, this attribute is available only in outbound-channel-adapter

JavaMailSenderImpl mailSender = new JavaMailSenderImpl();

            mailSender.setHost("imap-mail.outlook.com");
            mailSender.setPort(993);

            Properties props = mailSender.getJavaMailProperties();
            props.put("mail.imap.ssl.enable", "true");
            props.put("mail.imap.auth.mechanisms", "XOAUTH2");
            props.put("mail.debug", "true");
            props.put("mail.debug.auth", "true");

            String authToken = beanOAuth.getAuthToken();

            Session session = Session.getInstance(props, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {

                    String token = beanOAuth.getAuthToken();

                    return new PasswordAuthentication(_smtpUser, token);
                }
            });

            session.setDebug(true);

            Store store = session.getStore("imap");
            store.connect("imap-mail.outlook.com", _smtpUser, authToken);

            mailSender.setSession(session);


            return mailSender;

@dmitryallen
Copy link
Author

It's my current configuration

2023-01-18 16_41_42-Window

@artembilan
Copy link
Member

Right. That's what I mean. The <mail:imap-idle-channel-adapter>, for example, has respective attribute:

		<xsd:attribute name="authenticator" type="xsd:string">
			<xsd:annotation>
				<xsd:documentation>
					Specify the jakarta.mail.Authenticator.
					NOTE: if this is provided, then 'session' should not be.
				</xsd:documentation>
				<xsd:appinfo>
					<tool:annotation kind="ref">
						<tool:expected-type type="jakarta.mail.Authenticator"/>
					</tool:annotation>
				</xsd:appinfo>
			</xsd:annotation>
		</xsd:attribute>

Same attribute is present on regular <mail:inbound-channel-adapter> polling channel adapter.
I agree that we don't document this attribute anyhow here: https://docs.spring.io/spring-integration/reference/html/mail.html#mail-namespace.
But nothing stops us to improve that end-user experience.

Let's us know if that option works for you as separate bean and we will document it respectively!

Not sure how dynamic OAuth works with Gmail to make respective changes in the current sample in this project...

@dmitryallen
Copy link
Author

Thanks Artem,
it's working well, so we can close this ticket.

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

No branches or pull requests

3 participants