fixed origin stuff

This commit is contained in:
Rudis Muiznieks 2023-04-30 15:54:06 -05:00
parent 82bc13de67
commit 1dea48554d
Signed by: rudism
GPG Key ID: CABF2F86EF7884F9
1 changed files with 48 additions and 29 deletions

View File

@ -22,8 +22,8 @@ public static class Program {
private static readonly string s_loginHtmlCache = File.ReadAllText(Path.Combine(
AppDomain.CurrentDomain.BaseDirectory, "login.html"));
private static readonly string s_domain = Environment
.GetEnvironmentVariable("WEBAUTHN_DOMAIN") ?? "localhost";
private static readonly string? s_domain = Environment
.GetEnvironmentVariable("WEBAUTHN_DOMAIN");
private static readonly string s_db = Environment
.GetEnvironmentVariable("WEBAUTHN_DB") ?? "credentials.db";
private static readonly long s_lifetime = long.Parse(Environment
@ -34,21 +34,31 @@ public static class Program {
private static readonly int s_port = int.Parse(Environment
.GetEnvironmentVariable("WEBAUTHN_PORT") ?? "5000",
CultureInfo.InvariantCulture);
private static readonly Fido2 s_fido2 = new(new Fido2Configuration {
ServerDomain = s_domain,
ServerName = "WebauthnProxy",
Origins = new(new[] { $"http{(
s_domain == "localhost"
? string.Empty
: "s")}://{s_domain}{(
s_domain == "localhost"
? $":{s_port}"
: string.Empty)}" }),
});
private static readonly Dictionary<string, Fido2> s_fido2 = new();
private static readonly List<PublicKeyCredentialDescriptor> s_keys = new();
private static string ConnectionString { get => $"Data Source={s_db}"; }
private static Fido2 GetFido2(HttpContext context) {
var origin = context.Request.Host.Value.Split(":").First();
Console.WriteLine($"origin {origin}");
if (!s_fido2.ContainsKey(origin)) {
s_fido2.Add(origin, new(new Fido2Configuration {
ServerDomain = origin,
ServerName = "WebauthnProxy",
Origins = new(new[] { $"http{(
origin == "localhost"
? string.Empty
: "s")}://{origin}{(
origin == "localhost"
? $":{s_port}"
: string.Empty)}" }),
}));
}
return s_fido2[origin];
}
public static void Main(string[] args) {
var app = Initialize(args);
app.UseSession();
@ -82,20 +92,25 @@ public static class Program {
if (context.Request.Cookies[COOKIE_NAME] == null)
return Task.CompletedTask;
context.Response.Cookies.Append(COOKIE_NAME, string.Empty, new CookieOptions {
var cookieOpts = new CookieOptions {
Path = "/",
Secure = true,
HttpOnly = true,
MaxAge = TimeSpan.Zero,
Domain = s_domain,
});
SameSite = SameSiteMode.None,
MaxAge = TimeSpan.FromSeconds(s_lifetime),
};
if (string.IsNullOrEmpty(s_domain)) {
cookieOpts.Domain = s_domain;
}
context.Response.Cookies.Append(COOKIE_NAME, string.Empty, cookieOpts);
context.Response.Redirect("/");
return Task.CompletedTask;
});
app.MapPost("/auth/key", async (context) => {
var options = s_fido2.GetAssertionOptions(
var options = GetFido2(context).GetAssertionOptions(
s_keys, UserVerificationRequirement.Discouraged);
context.Session.SetString(SESS_ASSERTION_KEY,
JsonSerializer.Serialize(options));
@ -134,7 +149,7 @@ public static class Program {
}
}
var res = await s_fido2.MakeAssertionAsync(
var res = await GetFido2(context).MakeAssertionAsync(
assertionResponse, opts, pubKey, 0, (_, _) => Task.FromResult(true));
if (res.Status != "ok") {
context.Response.StatusCode = 401;
@ -142,17 +157,21 @@ public static class Program {
return;
}
context.Response.Cookies.Append(
COOKIE_NAME,
GenerateToken(connection),
new CookieOptions {
var cookieOpts = new CookieOptions {
Path = "/",
Secure = true,
HttpOnly = true,
SameSite = SameSiteMode.None,
Domain = s_domain,
MaxAge = TimeSpan.FromSeconds(s_lifetime),
});
};
if (string.IsNullOrEmpty(s_domain)) {
cookieOpts.Domain = s_domain;
}
context.Response.Cookies.Append(
COOKIE_NAME,
GenerateToken(connection),
cookieOpts);
await context.Response.WriteAsJsonAsync(new { status = "ok" });
});
@ -162,7 +181,7 @@ public static class Program {
Name = "Default User",
DisplayName = "Default User",
};
var options = s_fido2.RequestNewCredential(
var options = GetFido2(context).RequestNewCredential(
user,
new List<PublicKeyCredentialDescriptor>(),
AuthenticatorSelection.Default,
@ -190,7 +209,7 @@ public static class Program {
var optsJson = context.Session.GetString(SESS_ATTESTATION_KEY);
context.Session.Remove(SESS_ATTESTATION_KEY);
var opts = CredentialCreateOptions.FromJson(optsJson);
var cred = await s_fido2.MakeNewCredentialAsync(
var cred = await GetFido2(context).MakeNewCredentialAsync(
req.Response, opts, (_, _) => Task.FromResult(true));
var descriptor = new PublicKeyCredentialDescriptor(
cred.Result!.CredentialId);