-
Notifications
You must be signed in to change notification settings - Fork 74
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
Users may be confused after showing intent to sign in but the sign-in is failed #488
Comments
Agreed. In addition, the RP might want to force an authentication, or the authentication level of assurance is not sufficient (both of which might trigger a re-authentication). |
Problem StatementThe FedCM API currently lacks a dedicated API surface that enables an IdP to return information about what went wrong and where to go from there to the RP or the browser. The only option is to overload the IdentityCredential.token parameter and rely on the API caller (IdP SDK, RP, or 3P library) to decode and display error messages. Unfortunately, this creates two problems:
A dedicated API surface would address these problems by providing a standard way for IdPs to return error information to RPs and/or users. This would allow IdPs to be confident that their errors would be handled correctly, and it would eliminate the need for RPs to special-case each IdP. This is a proposal to introduce an API to inform the user agent about errors and handle them consistently across IdPs. ProposalIn this proposal, to guarantee to IdPs that errors are shown to inform users that their sign-in attempt has failed, the browser can support displaying error dialogs. To start with, a general purpose error dialog can cover a lot of cases and guarantee that users are notified in a consistent manner across RPs and IdPs. For example: While the general purpose error dialog is better than the status quo, there are known error cases where a more purpose-specific dialog could give users more specific information. Therefore, it would be better if the browser can show some specific error dialogs to give the user more context. For example: The enumeration of specific errors could be insufficient and it’s possible that users would want to learn more about the error and potentially some next steps to fix the error. Therefore the browser can provide some affordance to achieve that, e.g. via a new “More details” button: When the user clicks the “More details” button, the browser can open a pop-up window to show a IdP controlled page with detailed information about the error.Proposed APIIn this proposal, to support the error dialogs described above, the browser introduces error codes and error urls that can be used whenever the IdP cannot produce a token. The IdP HTTP APIIn the
codeOPTIONAL. The IdP can use the “code” field to specify one of the known errors from
The list is based on the OAuth 2.0 error response table to cover common errors across IdPs. If a valid If an urlOPTIONAL. A URL identifying a human-readable web page with information about the error, used to provide additional information about the error to users. The uri must be of the same-origin as the IdP
This field is useful to users because browsers cannot provide rich error messages on a native UI. e.g. links for next steps, customer service contact information etc.. If a user wants to learn more about the error details and how to fix it, they could visit the provided page from the browser UI for more details. Note
The Client JS APITo give more context to the API caller such that they could provide more sign-in options to users, the browser can pass over the error (
Privacy ConsiderationsThe new Error Response API is only invoked post user permission to allow RP/IdP communication. e.g. the user is aware that they are “signing in to RP with IdP”. In addition, the IdP has already possessed both the RP information and the user cookie from the Security ConsiderationsWhen the user clicks the “More details” button, we open a popup (same UI and web platform properties as what one would get with window.open(url,””,”popup,noopener,noreferrer”)) that loads the PhisingThe primary threat is a phishing attack, where the attacker (who controls - or colludes with - both the RP as well as the IdP) can provide a fake “error.url” (that impersonates a real IdP) for the browser to display via the pop-up window, and trick the user to enter their (real IdP) password there. e.g. upon user clicking the “More details” button, the browser will open a page that looks like a genuine “Sign in to IdP” website. Then the user “may” be tricked into entering their IdP credentials on that website. Because of that, the pop-up window has the following properties:
As such, the attack has to rely on the fact that the user misses the displayed origin/site in both steps and on safe browsing not knowing about the site. In addition to that, the attacker may already be able to do this by opening a phishing pop-up window and there’s no browser UI involved compared to this proposal. Considered AlternativesAPI caller handles all errorsThe browser could delegate handling the errors to the API callers (RP or IdP SDK or FedCM library owned neither by RP nor IdP). When the browser receives the errors from the token request, it rejects the promise with the errors. Once the API caller receives the error, the caller can inform users accordingly. e.g. the caller can render an iframe to show proper information to users. Pros
Cons
Appendix
|
Since the error is anyway exposed to the RP ("The Client JS API"), wouldn't it make more sense to let the RP take care of showing error messages (which it could do without a popup), and let this just be a proposal about exposing the error type to the RP? |
Having the API caller rendering the UI does have benefits as mentioned in the considered alternatives section. That said, there's no guarantee that the API callers would do it and the UX would be bad if they don't. In addition, when it comes to multi-IdPs, it would be challenging for them to implement a proper UI affordance to show error messages. |
As noted in the call:
|
Thanks Achim for following up!
This is indeed a possible solution and we started with it when developing this feature. It's worth noting that this may lead to suboptimal UX. In Chrome, the error page will be displayed in a pop-up window on desktop and in a CCT (ChromeCustomTab) on Android. For UI that's as loud as a pop-up or CCT, it should provide as much value as possible. In the AuthZ API (name TBD), user can grant calendar access to finish the sign-in flow; in IdPLoginStatus API, user can sign in to IdP via the pop-up. However, for the error page, it's unlikely to be call-to-action. Rather, it's likely to just provide some information about the error itself. Therefore we believe that it should be gated by a quieter UI and only be displayed if user wants to "learn more". Ideally the browser UI can provide meaningful strings such that the user doesn't need to open the loud UI.
Unfortunately IdP doesn't have a reliable way to do it. If FedCM API is called by RP directly (or via 3P library) without using IdP SDK, then the error may not be (properly) handled. This could be concerning to IdPs. Even if an IdP SDK is used, when it comes to multiple IdP, it's possible that different IdPs handle errors differently which could cause inconsistent UX on the same RP. |
I'm good with having both options - both paths should be generally possible though.
That's not what I meant - I was referring to this:
Given this error UI is shown post consent why not simply define
IDP can use the strings they'd want from any standard they want to use, if this a IDP controlled UX This should also be passed back to the RP in case they'd want to react to this. |
Hi Achim, allowing customized error description occurred to us as well. We should have mentioned it in the "Considered Alternatives" section. Sorry about that! The question is: whether / how much should the browser allow random strings on its native UI. The conclusion we have at least in Chrome is that it should be "little to none" from security's perspective. We shared the same principle when designing the RP context API where we only allow 4 predefined strings (sign in, sign out, user, continue) instead of accepting customized ones. From extensibility's perspective, we allow random error string in WDYT? |
From a thread model perspective this seems a different case given this is shown in the account selector during the main mediation. Whereas the error is an alternative to passing a token to the RP post user interaction.
If the generic error UI is mandatory than no IDP or RP would mind showing a second error honestly, the error JSON passed to the RP is then likely only used for failure analysis. Its an additional complexity for browsers and IDP (supported error codes + no ability for a bespoke description (which is left open to the IDP in OAuth/OpenID) - not a deal breaker but makes continue_on even more pressing as a different option. |
@asr-enid can you clarify what is your preferred behavior? In particular, how should errors be handled if the IDP id assertion endpoint has some network error? |
Alternatively the IdP can provide an error URL without a predefined code. The browser can then construct the UI with generic error string + a "More details" button. If the user is interested, they can definitely learn about the detailed error from the pop-up window. If they are not interested, we don't need to show the loud UI which also respects the user's choice (not interested). |
In this case a generic error UX seems sensible as the browser won't have any information available (an error JSON) and the browser mediated flow just fails technically. Would something be passed back to the caller in this case? Overall the approach suggested is doable I guess, but as noted managing the supported codes to avoid having the IDP provide the content directly can become a burden. I made the case for continue_on already. If these things are optional / available for the IDP they can decide which path to follow given the scenario at hand |
continue_on would additionally adress cases where the login needs extra work or re-authentication as noted by @philsmart as the error can be avoided if the user is able to take the necessary action. |
|
Agreed |
@samuelgoto seems this should be a proposal under https://github.com/fedidcg/FedCM/tree/main/proposals ? |
Currently after a user has granted permission to sign in to an RP with IdP (e.g. by clicking on the "Continue as" button on the account UI), the browser will send a request to the id_assertion_endpoint to fetch an IdentityProviderToken. If a token is issued, the browser will hand it over to the API caller and the user will continue their journey on the website.
However, the IdP could refuse to issue an token. To name a few:
Today when the IdP refuses to issue an token, FedCM API will reject the promise and fail the request silently.
From user's perspective, after they have granted permission to sign in, they may be confused because they are neither signed in nor informed about the failure. It would be helpful if there's a way for keep users in the loop for better user experience.
The text was updated successfully, but these errors were encountered: