rudy999 2 Posted December 17, 2021 I have seen the ICS demos and have successfully used the following components: TSslSmtpCli TSslContext TIcsRestEmail to connect and send emails from a user - based application, = outlook office, Microsoft Azure with proper API permissions for authentication. However, I cannot see this working for a Service-based application where there is no one logged in for the web page to appear. (send emails only, no need to read) Is there a demo or instructions if this is possible to implement? thank you in advance Share this post Link to post
Angus Robertson 577 Posted December 17, 2021 I assume you are referring to an OAuth2 login page appearing in a browser during authentication. For Google, the Refresh Token you receive after an interactive OAuth2 login remains effective for several months or longer, generally, so can be used by services, believe this is the case with Microsoft as well, but don't recall from testing. Your service can email an admin to update the token manually if it expires. You must store the Refresh Token securely as if it were a password, because that's really what it is, it is used by OAuth2 to get a new 12 hour or something Application Token which is the one you use to access APIs. If you set AuthType to OAuthTypeMan, an event will be called in which you can send the email. The event could launch an interactive application, if the service is running on PC with someone watching the screen. Angus Share this post Link to post
rudy999 2 Posted December 21, 2021 " I assume you are referring to an OAuth2 login page appearing in a browser during authentication " <<That is correct. The token I use with Microsoft Azure seems to be for 1 hour. For the non-service app this is not an issue and the browser pops up but the app continues. " Your service can email an admin to update the token manually if it expires. " <<Is this practical?How can the service email without a valid token? **The service runs on an unattended PC that is not the same as the working app** Thunderbird is a non-MS app that uses OAUTH2 and the browser pop up does not occur. So I thought that it was possible, even for an interactive app. Any ideas are appreciated. thks Share this post Link to post
Angus Robertson 577 Posted December 21, 2021 I think you are confusing the two tokens that OAuth2 should return. In ICS, AccToken property is the short lived token used for HTTP requests. The RefreshToken property is a long lived token that you should store safely like a password, and may be used repeatedly by the component to refresh AccToken, in background without any interaction. I tested GMail yesterday, and the saved refresh token meant it just worked without a new login. So you need to check if Azure is returning a refresh token and whether you are saving it for re-use. You may need to provide specific scope settings to get a refresh token, see the constant OAuthUriMSRest. Angus Share this post Link to post
rudy999 2 Posted December 21, 2021 Angus, I know I am confused... Thank you for your patience. I see that I am obtaining both a RefrToken string AND AccToken string. I am NOT saving the RefrToken string, at the moment. The AccToken has an expiry datetime which is one (1) hour into the future of the request moment. As a test, I did hard code the RefrToken into the SslSmtpClient.OAuthToken property and when I sent an email, there was NO web login authorization web page and the email was sent successfully. As you indicated, the RefrToken is the long-lived token. Is there a property on SslSmtpClient or ICsResetEmail that shows the expiry date of this token? A quick web search shows it is 90 days vs 1 hour for the AccToken. Question=with a proper RefrToken can I then use GetNewToken(False) or how would that be done? thanks in advance Share this post Link to post
rudy999 2 Posted December 21, 2021 Update - I just noticed that if I initially use a RefrToken for the SslSmtpClient when sending, I get a NEW RefrToken. so if I save this new RefrToken and re-use it the next time this can continue and never need the web page authorization? regards Share this post Link to post
Angus Robertson 577 Posted December 21, 2021 Provided you have set the RefrToken or RefreshToken property, you won't see a login window. It;'s expiry is unknown to the application, but can happen if the account secrets are changed, if you invalidate it through the online console, or at the whim of Google or Microsoft. So applications need to handle token failure, as I mentioned a couple of days ago. The same refresh token can be used on multiple computers, at least for Gmail which is the service I use regularly as a backup when my own SMTP server is down. This why the ICS MailQueue component handles multiple email servers, with OAuth2. Angus Share this post Link to post
John Kouraklis 94 Posted December 21, 2021 I've spend a lot of time into OAuth authentication. I am not familiar with ICS components but normally when you need to interact with an OAuth service the process would be the following: 1. If you have an access token, then attempt the request 2. If it fails due to authorisation, then use the refresh token to update the access token 3. if this fails, then a new refresh token is needed and the user needs to repeat the whole process You can avoid all these attempts if you check programmatically whether an access token has expired before any opartion Most of the components I am aware of, refresh the tokens automatically until they reach #3 where they launch the browser. What I find annoying here is that this behaviour with the browser is automated and disturbs the normal operations of an application Share this post Link to post
Angus Robertson 577 Posted December 21, 2021 All that happens internally within the ICS TRestOAuth component, it holds the expiry date so knows when to refresh the access token. Getting a new refresh token has various options since many applications are used unattended, not just Windows services, so it will notify an administrator that a new OAuth2 login us required, but API access will fail until it happens. It is unfortunate that OAuth2 was designed without a refresh expiry date being known, so things could be planned better. Angus Share this post Link to post
rudy999 2 Posted December 21, 2021 update: I have it working to my satisfaction. Thank you for your pointing me in the direction to a solution. I did have to 'store' the token securely and update it if it is refreshed. (I might have the terms wrong, but it works) Best regards all Share this post Link to post