Blazor server login form doesn't see values inputted by password manager

293 Views Asked by At

I have very simple registration and login page written in Blazor server.

When login+password is autofilled by Dropbox password manager, the login+password are visually filled into the input fields on the page, but binding doesn't work correctly and blazor doesn't set these values into string properties.

The login works when used without any password manager, for example chrome autofill works ok. But when used with Dropbox password manager, it doesn't work.

Here is screenshot of the login form in the example app - when login+password is filled by Dropbox Password Manager, notice that the validation says there is not email nor password and OnValidSubmit is NOT fired.

Blazor not aware of filled values

The login form is what you would expect, nothing special, just vanilla blazor:

Login blazor page

What can I change to make my login page work with passwords managers?

1

There are 1 best solutions below

0
On

I have the same issue.

When login page is navigating through a link without force refreshing then inputs became interactive before browser autofills it (I think) and input components take passing by browser values. But if login page is loading on start (launchUrl is set in profile, for example) or from mvc controller (LocalRedirect / Redirect) then after autofilling input values stay empty and can take values after user is clicking on any element on a screen.

Manual dispatching event does not take that effect.

As workaroung there are two css classes can be added, one that makes filled values transparent and one for showing values:

/* https://stackoverflow.com/questions/2781549/removing-input-background-colour-for-chrome-autocomplete */

.autofilled-not-touched input:-webkit-autofill,
.autofilled-not-touched input:-webkit-autofill:hover, 
.autofilled-not-touched input:-webkit-autofill:focus, 
.autofilled-not-touched input:-webkit-autofill:active,
.autofilled-not-touched input:-internal-autofill-selected{
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    transition: background-color 5000s ease-in-out 0s;
    box-shadow: inset 0 0 0px 1000px #00000000;
    caret-color: transparent;
}


.autofilled-touched input:-webkit-autofill,
.autofilled-touched input:-webkit-autofill:hover, 
.autofilled-touched input:-webkit-autofill:focus, 
.autofilled-touched input:-webkit-autofill:active,
.autofilled-touched input:-internal-autofill-selected{
    -webkit-background-clip: text;
    -webkit-text-fill-color: var(--mud-palette-text-primary);
    transition: background-color 5000s ease-in-out 0s;
    box-shadow: inset 0 0 0px 1000px #0000FF09;
    caret-color: var(--mud-palette-text-primary);
}

After user is clicking on any element (window or input box) binded login model is taking values. We can add handler invoked after that to change class of a form (or other inputs parent):

<EditForm Model="@model" OnValidSubmit="OnValidSubmit" class="@_class" >
    ...
    <MudTextField Label="Login"
                  Variant="Variant.Outlined"
                  @bind-Value="model.Username"
                  @bind-Value:after="@TryTouch"
                  autocomplete="username"
                  />

    <MudTextField Label="Password"
                  Variant="Variant.Outlined"
                  InputType="InputType.Password"
                  @bind-Value="model.Password"
                  autocomplete="current-password"
                  />
private bool _isTouched;
private string _class = "autofilled-not-touched";

private void TryTouch()
{
    if (!_isTouched)
    {
        _class = "autofilled-touched";
        _isTouched = true;
    }
}