Second sign-in with Windows Hello results in error on the token endpoint
Short description:
Login to our application first succeeds using Azure AD - Windows Hello.
Upon session timeout, the Windows Hello seems to succeed on the web client, but backend receives an error instead of a token when sending the received the code.
The successful step 1 is:
Web client = 1. User login -> Redirect to ms login -> Obtain code -> Pass code to backend
Backend = Send code to token endpoint -> receive token -> establish session
When the session expires, the Web client is rejected by the backend and goes to the ms login again. There it receives the code (without any prompt) and passes it to the backend.
The failed step 2 is:
Web client = 1. Session expired (401) -> Redirect to ms login -> Obtain code -> Pass code to backend
Backend = Send code to token endpoint -> Bad request (400)
The issue is that the backend receives a Bad request (400) instead of the expected token.
If username/password (not Windows Hello) authentication for ms login is used, the step 2 succeeds.
Details:
Our web application supports Azure AD login for B2B and internal users. We use the https://login.microsoftonline.com/common/oauth2/v2.0/authorize?... endpoint for the login. Login without using the Sign-in-options works without issues.
If we select the "Sign-in options" on the Azure AD login page (login.microsoftonline.com) and then select "Sign in with Windows Hello or a security key".
The initial login is OK:
- the browser receives the code
- the application backend transmits the code to the token endpoint and receives the id token
I then clear the web application cookie - simulating a session timeout.
The application requires another login and redirects to the Azure AD login endpoint.
- Since the Azure AD login cookies are still valid, the browser receives the code without any user interaction.
- the application backend transmits the code to the token endpoint, but receives a 400 Bad request error in return.
The first and second request from the backend are identical.
The same scenario, when not using "Sign in with Windows Hello or security key", returns a valid token.
Example details of the token request:
Request (encoded as JSON, removed sensitive data):
{"client_id":"","redirect_uri":"https://","client_secret":"***","code":"0.ASAAJJm-YDCg0E-Q5abgNcQW6B7no_WCtMhPoi8zrAtQPdsgAAA.AQABAAIAAAD--DLA3VO7QrddgJg7WevrVRSIqdyTEl9zeLH_LWGrG5-6Uoo0PRbdt2elEZdVxHr0-x6vDS_9OdJGS4RQJcJhZEEr9akDs4HNSN7m8Iw1LhLouhPg-ZBmKjDaa5TBtW_4qISKkVHLQqlPeW9J30GwZU3eDFINEDflQ_pcol0u5sCjl2hBKAMtxy1HuPVq_5pgdJphCHY3E4ZYsF8jHOvDDNz2ud8ajDSh89r8HTBzMJ5xVFDHwXngLezkxX1qRx0zwGoUNHFFhV51C4bkhoVRNE85gKc98ErGXS3JX4nUigCFeynyLbiU7S673HozDo1i2MnnN2c2vHeITQUaSREAEwnH-mKQMrbEpIaI-wm5TAu2WKuUw03WCMbAbPBDGMh6QWa6aBPD1Imnz1NTwkO8eLypHQMau5KLdswUVQKMcJWQst_De_rwJfn4DFfOD9SKAb9MMbUL4xNZH-3euXVOhHJ1SN-EIebinQGuJ8U7DIFPINezluGw7stHMvzmI2bFGYlC2ApJDcf1pISCyDIfVwoBujUNbWxy-MU0CIZvv8NN0caU3IwrmjrZrESMPORJhZET0O8eJRyt7UMTRO8I-N2WlS_FD-Lvie-QgETtWL2M1FQxBJZvhPozllW9Hpno9FZgYsIigjejc4iflrMQgN131lgafuumR1Eg5l3BI5XOXOBruQGeLyicSq5AS8KAqJnM4PS7T16fCjQ4YYvfsEc7LxV2pkPv2g3hTcEzlDe8kIEpem05Hou7kLhcLlggAA","grant_type":"authorization_code"}
Response (encoded as JSON):
{"Version":{"Major":1,"Minor":1,"Build":-1,"Revision":-1,"MajorRevision":-1,"MinorRevision":-1},"Content":{"__type":"System.Net.Http.StreamContent, System.Net.Http","Headers":[{"Key":"Content-Length","Value":["436"]},{"Key":"Content-Type","Value":["application/json; charset=utf-8"]},{"Key":"Expires","Value":["-1"]}]},"StatusCode":"BadRequest","ReasonPhrase":"Bad Request","Headers":[{"Key":"Pragma","Value":["no-cache"]},{"Key":"Strict-Transport-Security","Value":["max-age=31536000; includeSubDomains"]},{"Key":"X-Content-Type-Options","Value":["nosniff"]},{"Key":"x-ms-request-id","Value":["794e6dde-9773-4bfb-a3f1-f9a1aecbb000"]},{"Key":"x-ms-ests-server","Value":["2.1.12071.7 - WEULR2 ProdSlices"]},{"Key":"Cache-Control","Value":["no-store, no-cache"]},{"Key":"P3P","Value":["CP=\"DSP CUR OTPi IND OTRi ONL FIN\""]},{"Key":"Set-Cookie","Value":["fpc=Ah_NngNDGVtHmMoKF5KoUQGaA2DvAwAAAHA63tgOAAAA; expires=Sat, 23-Oct-2021 09:06:33 GMT; path=/; secure; HttpOnly; SameSite=None","x-ms-gateway-slice=estsfd; path=/; secure; httponly","stsservicecookie=estsfd; path=/; secure; samesite=none; httponly"]},{"Key":"Date","Value":["Thu, 23 Sep 2021 09:06:32 GMT"]}],"RequestMessage":{"Version":{"Major":1,"Minor":1,"Build":-1,"Revision":-1,"MajorRevision":-1,"MinorRevision":-1},"Content":{"__type":"System.Net.Http.FormUrlEncodedContent, System.Net.Http","Headers":[{"Key":"Content-Type","Value":["application/x-www-form-urlencoded"]},{"Key":"Content-Length","Value":["1055"]}]},"Method":{"Method":"POST"},"RequestUri":"https://login.microsoftonline.com/common/oauth2/v2.0/token","Headers":[],"Properties":{}},"IsSuccessStatusCode":false}
Any idea what we can do to resolve the issue?