public IActionResult MakeCredentialOptions([FromForm] string username, [FromForm] string displayName, [FromForm] string attType, [FromForm] string authType, [FromForm] bool requireResidentKey, [FromForm] string userVerification) { try { if (string.IsNullOrEmpty(username)) { username = $"{displayName} (Usernameless user created at {DateTime.UtcNow})"; } // 1. Get user from DB by username (in our example, auto create missing users) var user = DemoStorage.GetOrAddUser(username, () => new Fido2User { DisplayName = displayName, Name = username, Id = Encoding.UTF8.GetBytes(username) // byte representation of userID is required }); // 2. Get user existing keys by username var existingKeys = DemoStorage.GetCredentialsByUser(user).Select(c => c.Descriptor).ToList(); // 3. Create options var authenticatorSelection = new AuthenticatorSelection { RequireResidentKey = requireResidentKey, UserVerification = userVerification.ToEnum <UserVerificationRequirement>() }; if (!string.IsNullOrEmpty(authType)) { authenticatorSelection.AuthenticatorAttachment = authType.ToEnum <AuthenticatorAttachment>(); } var exts = new AuthenticationExtensionsClientInputs() { Extensions = true, UserVerificationIndex = true, Location = true, UserVerificationMethod = true, BiometricAuthenticatorPerformanceBounds = new AuthenticatorBiometricPerfBounds { FAR = float.MaxValue, FRR = float.MaxValue } }; var options = _lib.RequestNewCredential(user, existingKeys, authenticatorSelection, attType.ToEnum <AttestationConveyancePreference>(), exts); // 4. Temporarily store options, session/in-memory cache/redis/db HttpContext.Session.SetString("key", options.ToJson()); var jsonOptions = HttpContext.Session.GetString("key"); this.test = jsonOptions; // 5. return options to client return(Ok(options)); } catch (Exception e) { return(Ok(new CredentialCreateOptions { Status = "error", ErrorMessage = FormatException(e) })); } }
public JsonResult MakeCredentialOptions([FromForm] string username, [FromForm] string attType, [FromForm] string authType, [FromForm] bool requireResidentKey, [FromForm] string userVerification) { try { // 1. Get user from DB by username (in our example, auto create missing users) var user = DemoStorage.GetOrAddUser(username, () => new User { DisplayName = "Display " + username, Name = username, Id = Encoding.UTF8.GetBytes(username) // byte representation of userID is required }); // 2. Get user existing keys by username List <PublicKeyCredentialDescriptor> existingKeys = DemoStorage.GetCredentialsByUser(user).Select(c => c.Descriptor).ToList(); // 3. Create options var authenticatorSelection = new AuthenticatorSelection { AuthenticatorAttachment = !string.IsNullOrEmpty(authType) ? AuthenticatorAttachment.Parse(authType) : null, RequireResidentKey = requireResidentKey, UserVerification = UserVerificationRequirement.Parse(userVerification) }; var options = _lib.RequestNewCredential(user, existingKeys, authenticatorSelection, AttestationConveyancePreference.Parse(attType)); // 4. Temporarily store options, session/in-memory cache/redis/db HttpContext.Session.SetString("fido2.attestationOptions", options.ToJson()); // 5. return options to client return(Json(options)); } catch (Exception e) { return(Json(new CredentialCreateOptions { Status = "error", ErrorMessage = FormatException(e) })); } }
public ContentResult Index(string username) { // 1. Get user from DB var user = DemoStorage.GetUser(username + "@example.com"); // 2. Get registered credentials from database var existingCredentials = DemoStorage.GetCredentialsByUser(user); var content = System.IO.File.ReadAllText("wwwroot/index.html"); var table = ""; foreach (var cred in existingCredentials) { var coseKey = PeterO.Cbor.CBORObject.DecodeFromBytes(cred.PublicKey); var kty = coseKey[PeterO.Cbor.CBORObject.FromObject(COSE.KeyCommonParameters.kty)].AsInt32(); var desc = ""; var icon = ""; try { var entry = _mds.GetEntry(cred.AaGuid); desc = entry.MetadataStatement.Description.ToString(); icon = entry.MetadataStatement.Icon.ToString(); } catch { } table += "<tr>" + "<td class=\"format no-wrap\">" + cred.CredType + "</td>" + "<td class=\"no-wrap\">" + cred.RegDate + "</td>" + "<td class=\"no-wrap\">" + cred.SignatureCounter.ToString() + "</td>" + "<td class=\"no-wrap\">" + cred.AaGuid.ToString() + "</td>" + "<td class=\"no-wrap\">" + desc + "</td>" + "<img src=" + icon + ">" + "<td>"; switch (kty) { case (int)COSE.KeyTypes.OKP: { var X = coseKey[PeterO.Cbor.CBORObject.FromObject(COSE.KeyTypeParameters.x)].GetByteString(); table += "<table class=\"sub-table\">" + "<tr>" + "<td><pre>X: " + BitConverter.ToString(X).Replace("-", "") + "</pre></td>" + "</tr>" + "</table>"; break; } case (int)COSE.KeyTypes.EC2: { var X = coseKey[PeterO.Cbor.CBORObject.FromObject(COSE.KeyTypeParameters.x)].GetByteString(); var Y = coseKey[PeterO.Cbor.CBORObject.FromObject(COSE.KeyTypeParameters.y)].GetByteString(); table += "<table class=\"sub-table\">" + "<tr>" + "<td><pre>X: " + BitConverter.ToString(X).Replace("-", "") + "</pre></td>" + "</tr>" + "<tr>" + "<td><pre>Y: " + BitConverter.ToString(Y).Replace("-", "") + "</pre></td>" + "</tr>" + "</table>"; break; } case (int)COSE.KeyTypes.RSA: { var modulus = coseKey[PeterO.Cbor.CBORObject.FromObject(COSE.KeyTypeParameters.n)].GetByteString(); var exponent = coseKey[PeterO.Cbor.CBORObject.FromObject(COSE.KeyTypeParameters.e)].GetByteString(); table += "<table class=\"sub-table\">" + "<tr>" + "<td><pre>Modulus: " + BitConverter.ToString(modulus).Replace("-", "") + "</pre></td>" + "</tr>" + "<tr>" + "<td><pre>Exponent: " + BitConverter.ToString(exponent).Replace("-", "") + "</pre></td>" + "</tr>" + "</table>"; break; } default: { throw new Fido2VerificationException(string.Format("Missing or unknown keytype {0}", kty.ToString())); } } } return(new ContentResult { ContentType = "text/html", StatusCode = (int)System.Net.HttpStatusCode.OK, Content = string.Format(content, username, table) }); }
public JsonResult MakeCredentialOptions([FromForm] string username, [FromForm] string displayName, [FromForm] string attType, [FromForm] string authType, [FromForm] bool requireResidentKey, [FromForm] string userVerification) { try { // user must already exist in Identity var identityUser = _users.FindByUsername(username); if (identityUser == null) { throw new Exception("User not found"); } if (!HttpContext.User.IsAuthenticated()) { throw new Exception("User is not authenticated"); } ; // 1. Get user from DB by username (in our example, auto create missing users) var user = PasswordlessStore.GetOrAddUser(username, () => new Fido2User { DisplayName = displayName, Name = username, Id = Encoding.UTF8.GetBytes(username) // byte representation of userID is required }); // 2. Get user existing keys by username var existingKeys = PasswordlessStore.GetCredentialsByUser(user).Select(c => c.Descriptor).ToList(); // 3. Create options var authenticatorSelection = new AuthenticatorSelection { RequireResidentKey = requireResidentKey, UserVerification = userVerification.ToEnum <UserVerificationRequirement>() }; if (!string.IsNullOrEmpty(authType)) { authenticatorSelection.AuthenticatorAttachment = authType.ToEnum <AuthenticatorAttachment>(); } var exts = new AuthenticationExtensionsClientInputs() { Extensions = true, UserVerificationIndex = true, Location = true, UserVerificationMethod = true, BiometricAuthenticatorPerformanceBounds = new AuthenticatorBiometricPerfBounds { FAR = float.MaxValue, FRR = float.MaxValue } }; var options = _fido2.RequestNewCredential(user, existingKeys, authenticatorSelection, attType.ToEnum <AttestationConveyancePreference>(), exts); // 4. Temporarily store options, session/in-memory cache/redis/db HttpContext.Session.SetString("fido2.attestationOptions", options.ToJson()); // 5. return options to client return(Json(options)); } catch (Exception e) { return(Json(new CredentialCreateOptions { Status = "error", ErrorMessage = FormatException(e) })); } }