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