Cannot use passkey/fido/webauthn in BlazorWebView.
- Dominant language
- C#
- Stars
- 23.3k
- Forks
- 2k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 290
Description
### Description
consider following code:
``` razor
@using Microsoft.JSInterop
@using System.Diagnostics
@inject HttpClient Http
@inject IJSRuntime JSRuntime
@if (_module is null)
{
loading...
}
else
{
Click Me
}
@code {
private IJSObjectReference? _module;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
_module = await JSRuntime.InvokeAsync("import", "./Home.razor.js");
StateHasChanged();
}
await base.OnAfterRenderAsync(firstRender);
}
private async Task PasskeyAsync(IJSObjectReference js)
{
try
{
var possible = await js.InvokeAsync("isWebAuthnPossible");
var response = await Http.PostAsJsonAsync("assertion-options", "username");
var options = await response.Content.ReadFromJsonAsync();
// exception thrown
var assertion = await js.InvokeAsync("verify", options);
}
catch (Exception ex)
{
Debug.Assert(ex.Message == "This is an invalid domain.\nundefined");
}
}
}
```
``` javascript
export function isWebAuthnPossible() {
return !!window.PublicKeyCredential;
}
export async function verify(options) {
if (typeof options.challenge === 'string')
options.challenge = fromBase64Url(options.challenge);
if (options.allowCredentials) {
for (var i = 0; i < options.allowCredentials.length; i++) {
const id = options.allowCredentials[i].id;
if (typeof id === 'string')
options.allowCredentials[i].id = fromBase64Url(id);
}
}
var creds = await navigator.credentials.get({ publicKey: options });
const response = creds.response;
const retval = {
id: creds.id,
rawId: toBase64Url(creds.rawId),
type: creds.type,
clientExtensionResults: creds.getClientExtensionResults(),
response: {
authenticatorData: toBase64Url(response.authenticatorData),
clientDataJSON: toBase64Url(response.clientDataJSON),
userHandle: response.userHandle && response.userHandle.byteLength > 0 ? toBase64Url(response.userHandle) : undefined,
signature: toBase64Url(response.signature)
}
}
return retval;
}
```
### Steps to Reproduce
1. Create a blazor hybrid app , see [docs](https://learn.microsoft.com/en-us/aspnet/core/blazor/hybrid/tutorials/windows-forms?view=aspnetcore-10.0)
2. create a component and js file above.
3. click button
### Link to public reproduction project repository
_No response_
### Version with bug
10.0.0-rc.2
### Is this a regression from previous behavior?
No, this is something new
### Last version that worked well
Unknown/Other
### Affected platforms
Windows
### Affected platform versions
_No response_
### Did you find any workaround?
For someone wants use passkey with winform app + blazor. Here is the temp solution:
1. create a empty winform app
2. add nuget package `Microsoft.Web.WebView2`
3. add `WebView2` control to your form by using winform designer.
4. right click the `WebView2` control-> Properties
5. set Dock: "Fill" , Source : "https://yourdomain.com/index.html"
6. publish your blazor webassembly(contains auth dance logic) to your server (yourdomain.com)
Helper link:
- [Get started with WebView2 in WinForms apps](https://learn.microsoft.com/en-us/microsoft-edge/webview2/get-started/winforms)
- [Host and deploy ASP.NET Core Blazor WebAssembly](https://learn.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/webassembly/?view=aspnetcore-9.0&tabs=windows)
### Relevant log output
```shell
```
Contributor guide
Research direction
Start with the Windows BlazorWebView reproduction and the Home.razor.js module shown in the report; run the passkey flow through navigator.credentials.get and capture the exception. Trace the JS interop and WebView host behavior around the reported invalid-domain failure. Done means the supplied flow works on Windows or the limitation and supported path are documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, javascript
- Domain
- authentication, desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100