Error refreshing access token with device authorisation grant (DAG) flow
Closed this issue · 2 comments
Hi guys,
first of all thanks a lot for the excellent piece of software :-)
I'm experiencing a refresh token issue when using device authorisation grant (DAG) flow:
Every time the access time is expired, I get errors like this:
2025-06-20 14:23:58: Error refreshing access token for account xxx@yyy.zzz - received invalid response: {'error': 'invalid_client', 'error_description': "AADSTS700025: Client is public so neither 'client_assertion' nor 'client_secret' should be presented. Trace ID: 86260b33-c971-4da3-b613-7570cacc1f00 Correlation ID: b7c78faf-d961-4d33-9692-d44607e9461f Timestamp: 2025-06-20 12:23:58Z", 'error_codes': [700025], 'timestamp': '2025-06-20 12:23:58Z', 'trace_id': '86260b33-c971-4da3-b613-7570cacc1f00', 'correlation_id': 'b7c78faf-d961-4d33-9692-d44607e9461f'}
2025-06-20 14:23:58: Caught exception while requesting OAuth 2.0 credentials for account xxx@yyy.zzz: {'error': 'invalid_client', 'error_description': "AADSTS700025: Client is public so neither 'client_assertion' nor 'client_secret' should be presented. Trace ID: 86260b33-c971-4da3-b613-7570cacc1f00 Correlation ID: b7c78faf-d961-4d33-9692-d44607e9461f Timestamp: 2025-06-20 12:23:58Z", 'error_codes': [700025], 'timestamp': '2025-06-20 12:23:58Z', 'trace_id': '86260b33-c971-4da3-b613-7570cacc1f00', 'correlation_id': 'b7c78faf-d961-4d33-9692-d44607e9461f'}
fyi.
I could fix that for me by tweaking OAuth2Helper.refresh_oauth2_access_token().
(I'm not a Python developer.)
@@ -860,9 +860,14 @@ def get_oauth2_credentials(username, password, reload_remote_accounts=True):
if access_token or refresh_token: # if possible, refresh the existing token(s)
if not access_token or access_token_expiry - current_time < TOKEN_EXPIRY_MARGIN:
if refresh_token:
response = OAuth2Helper.refresh_oauth2_access_token(token_url, client_id, client_secret,
jwt_client_assertion, username,
if oauth2_flow == 'device':
response = OAuth2Helper.refresh_oauth2_access_token(token_url, client_id, None,
None, username,
cryptographer.decrypt(refresh_token))
else:
response = OAuth2Helper.refresh_oauth2_access_token(token_url, client_id, client_secret,
jwt_client_assertion, username,
cryptographer.decrypt(refresh_token))
access_token = response['access_token']
config.set(username, 'access_token', cryptographer.encrypt(access_token))
my config
[SMTP-1587]
documentation = *** note: this server will work for both Office 365 and personal Outlook/Hotmail accounts ***
server_address = smtp-mail.outlook.com
server_port = 587
server_starttls = True
local_address = 127.0.0.1
[learning@euro-fusion.org]
permission_url = https://login.microsoftonline.com/tenant_id/oauth2/v2.0/devicecode
token_url = https://login.microsoftonline.com/tenant_id/oauth2/v2.0/token
oauth2_scope = https://outlook.office.com/SMTP.Send offline_access
oauth2_flow = device
client_id = xxx
client_secret = xxx
I'm starting the email proxy with python emailproxy.py --external-auth --no-gui --debug
Thanks for you help ...
Thanks for reporting this. If your client doesn't require a secret, you should remove the whole of this line from the proxy's configuration file. Do you still encounter the problem if you do this?
Ah, actually, I was not aware that DAG with M365 doesn't really require at token (-> client_secret).
That's perfect, as expiring tokens are always a pain.
Just tried and confirmed that everythings works smoothly without client_secret:
-> initial access + subsequent access + refreshing
Thanks a lot for your precious feedback.
Will close the issue right now.