<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
I would like to authenticate users that use the PLAIN mechanism
against an oauth2 idp (in this case it's an Azure AD B2C).<br>
I configured dovecot.conf with<br>
<br>
<font face="monospace">auth_mechanisms = plain oauthbearer xoauth2<br>
passdb {<br>
driver = oauth2<br>
mechanisms = plain login<br>
args = /etc/dovecot/dovecot-oauth2.plain.conf.ext<br>
}</font><br>
<br>
and in /etc/dovecot/dovecot-oauth2.plain.conf.ext I have<br>
<br>
<font face="monospace">grant_url =
<a class="moz-txt-link-freetext" href="https://simons0f7b2c.b2clogin.com/simons0f7b2c.onmicrosoft.com/B2C_1_ROPC_Auth/oauth2/v2.0/token?scope=xxxxx-5be3-405a-babb-xxxx">https://simons0f7b2c.b2clogin.com/simons0f7b2c.onmicrosoft.com/B2C_1_ROPC_Auth/oauth2/v2.0/token?scope=xxxxx-5be3-405a-babb-xxxx</a><br>
client_id = xxxxx-5be3-405a-babb-xxxx<br>
client_secret = m6xxxxxxxx<br>
username_attribute = extension_PreferredLoginUsername<br>
#introspection_url = <a class="moz-txt-link-freetext" href="http://localhost:8000/introspect">http://localhost:8000/introspect</a><br>
#introspection_mode = post<br>
use_grant_password = yes<br>
debug = yes<br>
pass_attrs = host=127.0.0.1 proxy=y proxy_mech=xoauth2
pass=%{oauth2:access_token}</font><br>
<br>
I can see that dovecot sends a request to simons0f7b2c.b2clogin.com
that looks like this:<br>
<br>
<font face="monospace">POST
/simons0f7b2c.onmicrosoft.com/B2C_1_ROPC_Auth/oauth2/v2.0/token?scope=xxxxx-5be3-405a-babb-xxxx
HTTP/1.1<br>
Host: simons0f7b2c.onmicrosoft.com<br>
Date: Tue, 04 Oct 2022 15:43:42 GMT<br>
User-Agent: dovecot-oauth2-passdb/2.3.16<br>
Content-Length: 169<br>
Connection: Keep-Alive<br>
Content-Type: application/x-www-form-urlencoded<br>
<br>
<a class="moz-txt-link-abbreviated" href="mailto:grant_type=password&username=sp12@31337.it&password=">grant_type=password&username=sp12@31337.it&password=</a><userpass>&client_id=xxxxx-5be3-405a-babb-xxxx&client_secret=m6xxxxxxxx<br>
</font><br>
and the response is something like<br>
<font face="monospace"><br>
HTTP/1.1 200 OK<br>
Cache-Control: no-store, must-revalidate, no-cache<br>
Content-Type: application/json; charset=utf-8<br>
Set-Cookie: x-ms-cpim-trans=; domain=simons0f7b2c.b2clogin.com;
expires=Thu, 04-Oct-2012 15:29:04 GMT; path=/; SameSite=None;
secure; HttpOnly<br>
x-ms-gateway-requestid: 6ce588cf-9e35-491e-8393-18da8ccbe2cd<br>
X-Frame-Options: DENY<br>
Public: OPTIONS,TRACE,GET,HEAD,POST<br>
Strict-Transport-Security: max-age=31536000; includeSubDomains<br>
X-Content-Type-Options: nosniff<br>
X-XSS-Protection: 1; mode=block<br>
Allow: OPTIONS<br>
Allow: TRACE<br>
Allow: GET<br>
Allow: HEAD<br>
Allow: POST<br>
Date: Tue, 04 Oct 2022 15:29:03 GMT<br>
Content-Length: 1003<br>
<br>
{"access_token":"eyJ0xxxxx9uIw","token_type":"Bearer","expires_in":"3600"}<br>
</font><br>
<br>
Decoding the access_token I can see that there is a field
extension_PreferredLoginUsername:<br>
<br>
<font face="monospace">{<br>
"typ": "JWT",<br>
"alg": "RS256",<br>
"kid": "X5eXk4"<br>
}.{<br>
"iss": <a class="moz-txt-link-rfc2396E" href="https://simons0f7b2c.b2clogin.com/xxxxx/v2.0/">"https://simons0f7b2c.b2clogin.com/xxxxx/v2.0/"</a>,<br>
"exp": 1664898983,<br>
"nbf": 1664895383,<br>
"aud": "xxxxx-5be3-405a-babb-xxxx",<br>
"idp": "LocalAccount",<br>
"sub": "969xxx7",<br>
"extension_PreferredLoginUsername": "s2",<br>
"tfp": "B2C_1_ROPC_Auth",<br>
"azp": "89xxxc0",<br>
"ver": "1.0",<br>
"iat": 1664895383<br>
}</font><br>
<br>
so the field extension_PreferredLoginUsername is there, but dovecot
says:<br>
<br>
<font face="monospace">dovecot: auth: Debug: http-client: conn
40.126.31.64:443 [1]: Got 200 response for request [Req1: POST
<a class="moz-txt-link-freetext" href="https://simons0f7b2c.b2clogin.com/simons0f7b2c.onmicrosoft.com/B2C_1_ROPC_Auth/oauth2/v2.0/token?scope=xxxxx-5be3-405a-babb-xxxx">https://simons0f7b2c.b2clogin.com/simons0f7b2c.onmicrosoft.com/B2C_1_ROPC_Auth/oauth2/v2.0/token?scope=xxxxx-5be3-405a-babb-xxxx</a>]:
OK (took 1016 ms + 327 ms in queue)<br>
dovecot: auth: Debug:
oauth2(<a class="moz-txt-link-abbreviated" href="mailto:sp12@31337.it,192.168.0.4">sp12@31337.it,192.168.0.4</a>,<p0vv9jbq3MrAqAAE>):
Password grant succeeded<br>
dovecot: auth: Debug:
oauth2(<a class="moz-txt-link-abbreviated" href="mailto:sp12@31337.it,192.168.0.4">sp12@31337.it,192.168.0.4</a>,<p0vv9jbq3MrAqAAE>):
Processing field access_token<br>
dovecot: auth: Debug:
oauth2(<a class="moz-txt-link-abbreviated" href="mailto:sp12@31337.it,192.168.0.4">sp12@31337.it,192.168.0.4</a>,<p0vv9jbq3MrAqAAE>):
Processing field token_type<br>
dovecot: auth: Debug:
oauth2(<a class="moz-txt-link-abbreviated" href="mailto:sp12@31337.it,192.168.0.4">sp12@31337.it,192.168.0.4</a>,<p0vv9jbq3MrAqAAE>):
Processing field expires_in<br>
dovecot: auth: Error:
oauth2(<a class="moz-txt-link-abbreviated" href="mailto:sp12@31337.it,192.168.0.4">sp12@31337.it,192.168.0.4</a>,<p0vv9jbq3MrAqAAE>): oauth2
failed: Password grant failed: No username returned<br>
dovecot: auth: Debug:
oauth2(<a class="moz-txt-link-abbreviated" href="mailto:sp12@31337.it,192.168.0.4">sp12@31337.it,192.168.0.4</a>,<p0vv9jbq3MrAqAAE>):
Finished passdb lookup<br>
dovecot: auth: Debug:
pam(<a class="moz-txt-link-abbreviated" href="mailto:sp12@31337.it,192.168.0.4">sp12@31337.it,192.168.0.4</a>,<p0vv9jbq3MrAqAAE>):
Performing passdb lookup</font><br>
<br>
<br>
So, why does dovecot say "No username returned"? The username is
there! Do I have to configure something else?<span class="jwtHeader"></span><span
class="jwtClaims"></span>
</body>
</html>