protected void Button1_Click(object sender, EventArgs e) { PfAuthParams pfAuthParams = new PfAuthParams(); pfAuthParams.Phone = txtPhone.Text; pfAuthParams.Mode = pf_auth.MODE_SMS_ONE_WAY_OTP; pfAuthParams.SmsText = "Digite o código <$otp$> para ter acesso ao sistema."; pfAuthParams.CertFilePath = Server.MapPath(".//pf//certs//cert_key.p12"); string otp; int callStatus, errorId; // o parâmetro "otp" contém a chave de acesso gerada pelo sistema e enviada para o telefone destino bool res = pf_auth.pf_authenticate(pfAuthParams, out otp, out callStatus, out errorId); // o código de status 'callStatus == 20' indica que o SMS foi enviado com sucesso if (callStatus == 20) { // guardar o código no SessionState para validar no próximo campo Session["otp"] = otp; Label1.Text = "SMS enviado com sucesso!"; } else { Label1.Text = "SMS não enviado - código de status: " + callStatus.ToString(); } }
private void button1_Click(object sender, EventArgs e) { if (txtUsername.Text != "test" || txtPassword.Text != "test") { MessageBox.Show("Intial user credentials invalid"); return; } PfAuthParams pfAuthParams = new PfAuthParams(); pfAuthParams.Username = txtUsername.Text; pfAuthParams.Phone = "8622664878"; pfAuthParams.Mode = pf_auth.MODE_SMS_ONE_WAY_OTP; pfAuthParams.CertFilePath = System.IO.Directory.GetCurrentDirectory() + "\\cert_key.p12"; if (pf_auth.pf_authenticate(pfAuthParams, out otp, out status, out error)) { MessageBox.Show("User must enter " + otp + " to continue!"); groupBox1.Enabled = false; groupBox2.Enabled = true; } else { MessageBox.Show("Status: " + status + " Error: " + error); otp = String.Empty; status = 0; error = 0; } }
public ActionResult Login(string alias, string phone) { // Add call details from the user database. PfAuthParams pfAuthParams = new PfAuthParams(); pfAuthParams.Username = alias + "@sqlninja.onmicrosoft.com"; pfAuthParams.Phone = phone; pfAuthParams.Mode = pf_auth.MODE_STANDARD; // Specify a client certificate // NOTE: This file contains the private key for the client // certificate. It must be stored with appropriate file // permissions. pfAuthParams.CertFilePath = System.Web.HttpContext.Current.Server.MapPath("~/Libraries/Cert/cert_key.p12"); // Perform phone-based authentication int callStatus; int errorId; if (pf_auth.pf_authenticate(pfAuthParams, out callStatus, out errorId)) { System.Diagnostics.Debug.WriteLine("Multi-Factor Authentication succeeded."); ViewBag.Message = ""; return View("CustomerTrendMain"); } else { System.Diagnostics.Debug.WriteLine("Multi-Factor Authentication failed."); ViewBag.Message = "Multi-Factor Authentication failed."; return View("Index"); } }
// // create_authenticate_message: generates an authenticate message to be sent // to the PhoneFactor backend. // // Return value: // a complete authentication xml message ready to be sent to the PhoneFactor backend // private static string create_authenticate_message( PfAuthParams pfAuthParams, bool asynchronous) { bool sms = pfAuthParams.Mode == MODE_SMS_TWO_WAY_OTP || pfAuthParams.Mode == MODE_SMS_TWO_WAY_OTP_PLUS_PIN || pfAuthParams.Mode == MODE_SMS_ONE_WAY_OTP || pfAuthParams.Mode == MODE_SMS_ONE_WAY_OTP_PLUS_PIN; bool two_way = pfAuthParams.Mode == MODE_SMS_TWO_WAY_OTP || pfAuthParams.Mode == MODE_SMS_TWO_WAY_OTP_PLUS_PIN; bool otp = pfAuthParams.Mode == MODE_SMS_TWO_WAY_OTP || pfAuthParams.Mode == MODE_SMS_ONE_WAY_OTP; bool phone_app = pfAuthParams.Mode == MODE_PHONE_APP_STANDARD || pfAuthParams.Mode == MODE_PHONE_APP_PIN; bool phone_app_pin = pfAuthParams.Mode == MODE_PHONE_APP_PIN; XmlDocument doc = new XmlDocument(); // start message // <pfpMessage></pfpMessage> XmlElement root = doc.CreateElement("pfpMessage"); root.SetAttribute("version", "1.5"); doc.AppendChild(root); // message header // <header></header> XmlElement header = doc.CreateElement("header"); root.AppendChild(header); XmlElement source = doc.CreateElement("source"); header.AppendChild(source); XmlElement component = doc.CreateElement("component"); component.SetAttribute("type", "pfsdk"); source.AppendChild(component); XmlElement element = doc.CreateElement("host"); element.SetAttribute("ip", pfAuthParams.IpAddress); element.SetAttribute("hostname", pfAuthParams.Hostname); component.AppendChild(element); // request // <request></request> XmlElement request = doc.CreateElement("request"); Random random = new Random(); if (pfAuthParams.RequestId == null || pfAuthParams.RequestId.Length == 0) pfAuthParams.RequestId = random.Next(10000).ToString(); request.SetAttribute("request-id", pfAuthParams.RequestId); request.SetAttribute("language", pfAuthParams.Language); request.SetAttribute("async", asynchronous ? "1" : "0"); request.SetAttribute("response-url", pfAuthParams.ResponseUrl); root.AppendChild(request); XmlElement auth_request = doc.CreateElement("authenticationRequest"); if (sms) auth_request.SetAttribute("mode", "sms"); if (phone_app) auth_request.SetAttribute("mode", "phoneApp"); request.AppendChild(auth_request); XmlElement customer = doc.CreateElement("customer"); auth_request.AppendChild(customer); element = doc.CreateElement("licenseKey"); element.InnerText = LICENSE_KEY; customer.AppendChild(element); element = doc.CreateElement("groupKey"); element.InnerText = GROUP_KEY; customer.AppendChild(element); element = doc.CreateElement("countryCode"); element.InnerText = pfAuthParams.CountryCode; auth_request.AppendChild(element); element = doc.CreateElement("authenticationType"); element.InnerText = "pfsdk"; auth_request.AppendChild(element); element = doc.CreateElement("username"); element.InnerText = pfAuthParams.Username; auth_request.AppendChild(element); element = doc.CreateElement("phonenumber"); element.SetAttribute("userCanChangePhone", "no"); element.InnerText = pfAuthParams.Phone; if (pfAuthParams.Extension != null && pfAuthParams.Extension.Length != 0) { element.SetAttribute("extension", pfAuthParams.Extension); } auth_request.AppendChild(element); element = doc.CreateElement("allowInternationalCalls"); element.InnerText = pfAuthParams.AllowInternationalCalls ? "yes" : "no"; auth_request.AppendChild(element); element = doc.CreateElement("applicationName"); element.InnerText = pfAuthParams.ApplicationName; auth_request.AppendChild(element); XmlElement pin_info = doc.CreateElement("pinInfo"); XmlElement pin_element = doc.CreateElement("pin"); if (pfAuthParams.Mode == MODE_PIN || pfAuthParams.Mode == MODE_SMS_TWO_WAY_OTP_PLUS_PIN) { string pinFormat; string pinFormatted; if (pfAuthParams.Sha1PinHash.Length == 0) { pinFormat = "plainText"; pinFormatted = pfAuthParams.Pin; } else { pinFormat = "sha1"; pinFormatted = pfAuthParams.Sha1PinHash; } pin_element.SetAttribute("pinFormat", pinFormat); if (pfAuthParams.Sha1PinHash.Length != 0) { pin_element.SetAttribute("sha1Salt", pfAuthParams.Sha1Salt); } pin_element.SetAttribute("pinChangeRequired", "no"); pin_element.InnerText = pinFormatted; } if (sms) { XmlElement sms_info = doc.CreateElement("smsInfo"); sms_info.SetAttribute("direction", two_way ? "two-way" : "one-way"); sms_info.SetAttribute("mode", otp ? "otp" : "otp-pin"); element = doc.CreateElement("message"); element.InnerText = pfAuthParams.SmsText; sms_info.AppendChild(element); if (pfAuthParams.Mode == MODE_SMS_TWO_WAY_OTP_PLUS_PIN) sms_info.AppendChild(pin_element); auth_request.AppendChild(sms_info); pin_info.SetAttribute("pinMode", MODE_STANDARD); } else if (phone_app) { XmlElement phone_app_auth_info = doc.CreateElement("phoneAppAuthInfo"); phone_app_auth_info.SetAttribute("mode", phone_app_pin ? "pin" : "standard"); XmlElement device_tokens = doc.CreateElement("deviceTokens"); element = doc.CreateElement("deviceToken"); if (pfAuthParams.NotificationType.Length > 0) { element.SetAttribute("notificationType", pfAuthParams.NotificationType); } element.InnerText = pfAuthParams.DeviceToken; device_tokens.AppendChild(element); phone_app_auth_info.AppendChild(device_tokens); element = doc.CreateElement("phoneAppAccountName"); element.InnerText = pfAuthParams.AccountName; phone_app_auth_info.AppendChild(element); if (phone_app_pin) { element = doc.CreateElement("pin"); element.SetAttribute("pinChangeRequired", "0"); string pinFormat; string pinFormatted; if (pfAuthParams.Sha1PinHash.Length == 0) { pinFormat = "plainText"; pinFormatted = pfAuthParams.Pin; } else { pinFormat = "sha1"; pinFormatted = pfAuthParams.Sha1PinHash; } element.SetAttribute("pinFormat", pinFormat); if (pfAuthParams.Sha1PinHash.Length != 0) { element.SetAttribute("sha1Salt", pfAuthParams.Sha1Salt); } element.InnerText = pinFormatted; phone_app_auth_info.AppendChild(element); } XmlElement phone_app_messages = doc.CreateElement("phoneAppMessages"); element = doc.CreateElement("message"); element.SetAttribute("type", "authenticateButton"); element.InnerText = "Authenticate"; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "authenticationDenied"); element.InnerText = "PhoneFactor authentication denied."; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "authenticationSuccessful"); element.InnerText = "You have successfully authenticated using PhoneFactor."; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "cancelButton"); element.InnerText = "Cancel"; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "closeButton"); element.InnerText = "Close"; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "denyAndReportFraudButton"); element.InnerText = "Deny and Report Fraud"; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "denyButton"); element.InnerText = "Deny"; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "fraudConfirmationNoBlock"); element.InnerText = "Your company's fraud response team will be notified."; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "fraudConfirmationWithBlock"); element.InnerText = "Your account will be blocked preventing further authentications and the company's fraud response team will be notified."; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "fraudReportedNoBlock"); element.InnerText = "Fraud reported."; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "fraudReportedWithBlock"); element.InnerText = "Fraud reported and account blocked."; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "notification"); element.InnerText = "You have received a PhoneFactor authentication request."; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "reportFraudButton"); element.InnerText = "Report Fraud"; phone_app_messages.AppendChild(element); if (pfAuthParams.Mode == MODE_PHONE_APP_STANDARD) { element = doc.CreateElement("message"); element.SetAttribute("type", "standard"); element.InnerText = "Tap Authenticate to complete your authentication."; phone_app_messages.AppendChild(element); } else { element = doc.CreateElement("message"); element.SetAttribute("type", "confirmPinField"); element.InnerText = "Confirm PIN"; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "newPinField"); element.InnerText = "New PIN"; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "pin"); element.InnerText = "Enter your PIN and tap Authenticate to complete your authentication."; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "pinAllSameDigits"); element.InnerText = "Your PIN cannot contain 3 or more repeating digits."; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "pinExpired"); element.InnerText = "Your PIN has expired. Please enter a new PIN to complete your authentication."; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "pinField"); element.InnerText = "PIN"; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "pinHistoryDuplicate"); element.InnerText = "Your PIN cannot be the same as one of your recently used PINs. Please choose a different PIN."; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "pinLength"); element.InnerText = "Your PIN must be a minimum of 4 digits."; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "pinMismatch"); element.InnerText = "New PIN and Confirm PIN must match."; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "pinRetry"); element.InnerText = "Incorrect PIN. Please try again."; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "pinSequentialDigits"); element.InnerText = "Your PIN cannot contain 3 or more sequential digits ascending or descending."; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "pinSubsetOfPhone"); element.InnerText = "Your PIN cannot contain a 4 digit subset of your phone number or backup phone number."; phone_app_messages.AppendChild(element); element = doc.CreateElement("message"); element.SetAttribute("type", "saveButton"); element.InnerText = "Save"; phone_app_messages.AppendChild(element); } phone_app_auth_info.AppendChild(phone_app_messages); auth_request.AppendChild(phone_app_auth_info); } else { pin_info.SetAttribute("pinMode", pfAuthParams.Mode); if (pfAuthParams.Mode == MODE_PIN) pin_info.AppendChild(pin_element); element = doc.CreateElement("userCanChangePin"); element.InnerText = "no"; pin_info.AppendChild(element); } auth_request.AppendChild(pin_info); return doc.InnerXml; }
// Deprecated - for backward compatibility only public static bool pf_authenticate_async( string username, string phone, string country_code, bool allow_int_calls, string sha1_pin_hash, string sha1_salt, string hostname, string ip, string cert_file_path, string response_url, out int call_status, out int error_id) { PfAuthParams pfAuthParams = new PfAuthParams(); pfAuthParams.Username = username; pfAuthParams.CountryCode = country_code; pfAuthParams.Phone = phone; pfAuthParams.AllowInternationalCalls = allow_int_calls; pfAuthParams.Mode = MODE_PIN; pfAuthParams.Sha1PinHash = sha1_pin_hash; pfAuthParams.Sha1Salt = sha1_salt; pfAuthParams.Hostname = hostname; pfAuthParams.IpAddress = ip; pfAuthParams.CertFilePath = cert_file_path; pfAuthParams.ResponseUrl = response_url; return pf_authenticate_internal( pfAuthParams, true, out call_status, out error_id); }
public static bool pf_authenticate_async( PfAuthParams pfAuthParams, out int callStatus, out int errorId) { return pf_authenticate_internal( pfAuthParams, true, out callStatus, out errorId); }
// PIN Mode with clear text PIN. public static bool pf_authenticate( string username, string phone, string country_code, bool allow_int_calls, string pin, string hostname, string ip, string cert_file_path, out int call_status, out int error_id) { PfAuthParams pfAuthParams = new PfAuthParams(); pfAuthParams.Username = username; pfAuthParams.CountryCode = country_code; pfAuthParams.Phone = phone; pfAuthParams.AllowInternationalCalls = allow_int_calls; pfAuthParams.Mode = MODE_PIN; pfAuthParams.Pin = pin; pfAuthParams.Hostname = hostname; pfAuthParams.IpAddress = ip; pfAuthParams.CertFilePath = cert_file_path; return pf_authenticate_internal( pfAuthParams, false, out call_status, out error_id); }
// // pf_authenticate, pf_authenticate_async: authenticates using PhoneFactor. // // Arguments: // 1) username: the username to be auth'd // 2) country_code: the country code to be used for the call. defaults to 1. // 3) phone: the phone number to PhoneFactor authenticate // 4) extension: the extension to dial after the call is connected // 5) allow_int_calls: a boolean value that determines whether international // calls should be allowed. defaults to false. note that this only needs to // be set to true if the call you are making is international, and thus could // cost you money. see www.phonefactor.net for the PhoneFactor rate table // that shows which calling zones will cost money and which are free. // 6) mode: specify whether to use "standard", "pin", "voiceprint", // "sms_two_way_otp" or "sms_two_way_otp_plus_pin" mode // standard: user presses # // pin: user enters their pin and # // voiceprint: user says their passphrase and their voice is matched // sms_two_way_otp: user responds to text with OTP // sms_two_way_otp_plus_pin: user responds to text with OTP + PIN // phone_app_standard: user selects Authenticate in phone app // phone_app_pin: user enters their pin and selects Authenticate in the phone app // 7) pin: PIN the user must enter during the call // 8) sha1_pin_hash: SHA1 encrypted PIN the user must enter during the call // 9) sha1_salt: SHA1 salt appended to PIN prior to encryption // 10) $application_name: Specify the appliation name to display on reports in the // PhoneFactor Management Portal. // 11) $device_token: Specify the device token of the device to send the // phone app notification to. // 12) $account_name: Specify the account name to display in the phone app. // 13) hostname: the hostname this authentication is being sent from. // defaults to 'pfsdk-hostname' // 14) ip: the ip address this authentication is being sent from. // defaults to '255.255.255.255' // 15) cert_file_path: the path and file name of the certificate file // 16) request_id: a string identifying the request that can be used to match // the asynchronous response to the original request // 17) response_url: the URL that the final response for an asynchronous request // should be sent to // 18) otp: One-time passcode (OTP) included in SMS text and returned for // one-way SMS. // 19) call_status: an integer code returned representing the status of the // phonecall. // 20) error_id: an integer code returned if the connection to the PhoneFactor // backend failed. // // Return value: // A boolean value representing whether the auth was successful or not. // If true, then the call_status and error_id output arguments can safely be // ignored. // // New implementations using class to pass parameters. public static bool pf_authenticate( PfAuthParams pfAuthParams, out string otp, out int callStatus, out int errorId) { return pf_authenticate_internal( pfAuthParams, false, out otp, out callStatus, out errorId); }
private static bool pf_authenticate_internal( PfAuthParams pfAuthParams, bool asynchronous, out string otp, out int call_status, out int error_id) { if (pfAuthParams.CountryCode.Length == 0) pfAuthParams.CountryCode = "1"; if (pfAuthParams.Hostname.Length == 0) pfAuthParams.Hostname = "pfsdk-hostname"; if (pfAuthParams.IpAddress.Length == 0) pfAuthParams.IpAddress = "255.255.255.255"; pfAuthParams.Mode = pfAuthParams.Mode.ToLower(); if (pfAuthParams.Mode != MODE_STANDARD && pfAuthParams.Mode != MODE_PIN && pfAuthParams.Mode != MODE_VOICEPRINT && pfAuthParams.Mode != MODE_SMS_TWO_WAY_OTP && pfAuthParams.Mode != MODE_SMS_TWO_WAY_OTP_PLUS_PIN && pfAuthParams.Mode != MODE_SMS_ONE_WAY_OTP && pfAuthParams.Mode != MODE_SMS_ONE_WAY_OTP_PLUS_PIN && pfAuthParams.Mode != MODE_PHONE_APP_STANDARD && pfAuthParams.Mode != MODE_PHONE_APP_PIN) pfAuthParams.Mode = MODE_STANDARD; otp = ""; call_status = 0; error_id = 0; string auth_message = create_authenticate_message(pfAuthParams, asynchronous); int tries = 1; if (mMutex.WaitOne()) { try { tries = mTargets.Count + 1; } finally { mMutex.ReleaseMutex(); } } for (int i = 0; i < tries; i++) { string response; if (send_message(mCurrentTarget, auth_message, pfAuthParams.CertFilePath, out response)) { string request_id_out = ""; bool authenticated = get_response_status(response, out request_id_out, out otp, out call_status, out error_id); return authenticated; } else { if (mMutex.WaitOne()) { try { mTargets.Enqueue(mCurrentTarget); mCurrentTarget = mTargets.Dequeue().ToString(); } finally { mMutex.ReleaseMutex(); } } } } return false; }
private static bool pf_authenticate_internal( PfAuthParams pfAuthParams, bool asynchronous, out int call_status, out int error_id) { string otp = ""; return pf_authenticate_internal(pfAuthParams, asynchronous, out otp, out call_status, out error_id); }
public async Task <ActionResult> Login(LoginViewModel model, string returnUrl) { if (ModelState.IsValid) { var user = await UserManager.FindAsync(model.Email, model.Password); if (user != null) { //await UserManager.SignInAsync(user, model.RememberMe); await SignInManager.SignInAsync(user, model.RememberMe, rememberBrowser : false); // Variables to store MFA results string otp = ""; int callStatus = 0; int errorId = 0; // Prepare the MFA Parameters PfAuthParams pfAuthParams = new PfAuthParams(); pfAuthParams.CountryCode = user.CountryCode; pfAuthParams.Phone = user.Phone; pfAuthParams.Pin = user.PIN.ToString(); // Load the certificate pfAuthParams.CertFilePath = System.Web.HttpContext.Current.Server.MapPath("~/pf/certs/cert_key.p12"); // Choose one of the below methods for authentication pfAuthParams.Mode = pf_auth.MODE_STANDARD; // a phone call without a pin //pfAuthParams.Mode = pf_auth.MODE_PIN; // pin //pfAuthParams.Mode = pf_auth.MODE_VOICEPRINT; // voice print //pfAuthParams.Mode = pf_auth.MODE_SMS_TWO_WAY_OTP; // sms him a one time password that he has to send back //pfAuthParams.Mode = pf_auth.MODE_SMS_TWO_WAY_OTP_PLUS_PIN; // sms him a one time password that he has to send back + pin // If using SMS, set the below according to the SMS mode //pfAuthParams.SmsText = "<$otp$>\nReply with this one-time passcode to complete your authentication."; //pfAuthParams.SmsText = "<$otp$>\nReply with this one-time passcode and your PIN to complete your authentication."; // Call the MFA Provider // the return value from the function is a boolean that is the result of // the authentication. Two out arguments are also returned. The first is the // result of the phonecall itself, the second is the result of the connection // with the backend. See call_results.txt for a list of call results // and descriptions that correspond to value returned. bool mfaResult = pf_auth.pf_authenticate(pfAuthParams, out otp, out callStatus, out errorId); // If MFA succeeded if (mfaResult == true) { return(RedirectToLocal(returnUrl)); } else { ModelState.AddModelError("", "Multi-factor Authentication failed."); } } else { ModelState.AddModelError("", "Invalid username or password."); } } // Сбои при входе не приводят к блокированию учетной записи // Чтобы ошибки при вводе пароля инициировали блокирование учетной записи, замените на shouldLockout: true var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout : true); switch (result) { case SignInStatus.Success: return(RedirectToLocal(returnUrl)); case SignInStatus.LockedOut: return(View("Lockout")); case SignInStatus.RequiresVerification: return(RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe })); case SignInStatus.Failure: default: ModelState.AddModelError("", "Неудачная попытка входа."); return(View(model)); } }