Welcome to Two Factor Authentication
Introduction
Two-factor authentication (2FA) is a security method that requires two forms of identification to verify a user's identity. It's a type of multi-factor authentication (MFA) that uses two authentication factors, such as a username and password, plus something you have, like a smartphone app. 2FA helps protect against phishing, social engineering, and password brute-force attacks.
C# (ASP.NET Core)
API Controller
namespace TwoFactorAuthentication.ApiControllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class TFAApiController : ControllerBase
{
public static string ConnectionString { get; set; }
public TFAApiController(IConfiguration configuration) {
ConnectionString = configuration.GetConnectionString("DefaultConnection");
}
[HttpPost]
public async Task<object> TFA_GetUserDetails(PtplUserApi ptpl)
{
var result = new ResultAPITFA();
try
{
if (ptpl == null || string.IsNullOrEmpty(ptpl.UserId))
{
result.resultstatus = false;
result.resultmessage = "Model is null";
return result;
}
var obj = SelectModelTFA<TFA_UserDetailsFromApi>("TFA_GetUserDetails", new { UserId = ptpl.UserId });
if (obj == null)
{
result.resultstatus = false;
result.resultmessage = "User not exists.";
}
else
{
result.resultstatus = true;
result.resultmessage = "Success";
result.resultdata = obj;
return result;
}
}
catch (Exception ex)
{
result.resultstatus = false;
result.resultmessage = "find some exception : " + ex.Message;
}
return result;
}
[HttpPost]
public async Task<object> TFA_UpdateUserDetails(PtplUserUpdateApi ptpl)
{
var result = new ResultAPITFA();
try
{
var param = new
{
UserId = ptpl.UserId ,
TFAIsEnabled = ptpl.TFAIsEnabled ,
TFASecurityStamp = ptpl.TFASecurityStamp ,
};
var obj = SelectModelTFA<int>("TFA_UpdateUserDetails", param);
if (obj == 0)
{
result.resultstatus = false;
result.resultmessage = "Data not update";
}
else
{
result.resultstatus = true;
result.resultmessage = "Success";
return result;
}
}
catch (Exception ex)
{
result.resultstatus = false;
result.resultmessage = "find some exception : " + ex.Message;
}
return result;
}
[HttpPost]
public async Task<object> TFA_Delete(PtplUserApi ptpl)
{
var result = new ResultAPITFA();
try
{
if (ptpl == null || ptpl.UserId == null)
{
result.resultstatus = false;
result.resultmessage = "Model is null, UserId not found";
return result;
}
var _user = await FindSecureSessionByUserIdAsync(ptpl.UserId);
if (_user == null)
{
result.resultstatus = false;
result.resultmessage = "Record not found. Invalid UserId.";
return result;
}
var portal = await GetPortalDetails(_user.RefererUrl);
if (portal == null)
{
result.resultstatus = false;
result.resultmessage = "User Portal not found.";
return result;
}
var enaled = await EnabledTFA(portal.UpdateUserAPIFullUrl, _user.UserId, "0", "");
if (!enaled)
{
result.resultstatus = false;
result.resultmessage = "Some went wrong user not update by api.";
return result;
}
var obj = SelectModelTFA<int>("TFA_Delete", new { UserId = ptpl.UserId });
if (obj == 0)
{
result.resultstatus = false;
result.resultmessage = "User deleting failed";
}
else
{
result.resultstatus = true;
result.resultmessage = "User Deleted.";
return result;
}
}
catch (Exception ex)
{
result.resultstatus = false;
result.resultmessage = "find some exception : " + ex.Message;
}
return result;
}
public async Task<SaveRequestUser> FindSecureSessionByUserIdAsync(string UserId)
{
return SelectModelTFA<SaveRequestUser>("FindSecureSessionByUserId", new { UserId });
}
public async Task<RegisteredPortal> GetPortalDetails(string RefererUrl)
{
return SelectModelTFA<RegisteredPortal>("GetPortalForAuth", new { PortalUrl = RefererUrl });
}
public async Task<bool> EnabledTFA(string UpdateUserAPIFullUrl, string UserId, string TFAIsEnabled, string TFASecurityStamp)
{
try
{
var param = new
{
UserId = UserId,
TFAIsEnabled = TFAIsEnabled,
TFASecurityStamp = TFASecurityStamp
};
var User = await PostTFA<ResultAPITFA>(null, UpdateUserAPIFullUrl, param);
return User.resultstatus;
}
catch (Exception ex)
{
return false;
}
}
public T SelectModelTFA<T>(string proc, object param)
{
var result = (dynamic)null;
try
{
using (var con = new SqlConnection(ConnectionString))
{
con.Open();
result = con.Query<T>(proc, param, null, commandTimeout: 60, commandType: CommandType.StoredProcedure).FirstOrDefault();
con.Close();
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
}
return result;
}
public async Task<T> PostTFA<T>(string _url, string ApiUrl, object param)
{
try
{
var result = (dynamic)null;
string apiBaseUrl = "";
using (HttpClient client = new HttpClient())
{
StringContent content = new StringContent(JsonConvert.SerializeObject(param), Encoding.UTF8, "application/json");
apiBaseUrl = _url + ApiUrl;
Uri myUri = new Uri(apiBaseUrl, UriKind.Absolute);
var Response = await client.PostAsync(myUri, content);
if (Response.StatusCode == System.Net.HttpStatusCode.OK)
{
string json = await Response.Content.ReadAsStringAsync();
result = JsonConvert.DeserializeObject<T>(json);
}
else
{
string json = await Response.Content.ReadAsStringAsync();
result = JsonConvert.DeserializeObject<T>(json);
}
}
return result;
}
catch (Exception ex)
{
throw;
}
}
public class ResultAPITFA
{
public bool resultstatus { get; set; }
public string resultmessage { get; set; }
public object resultdata { get; set; }
}
public class RegisteredPortal
{
public string UpdateUserAPIFullUrl { get; set; }
}
public class SaveRequestUser
{
public string UserId { get; set; }
public string UserName { get; set; }
public string Mobile { get; set; }
public string RefererUrl { get; set; }
public string RequestIP { get; set; }
public string SetupKey { get; set; }
public string SecurityStamp { get; set; }
public int Timestamp { get; set; }
public int PageReload { get; set; }
public string PortalName { get; set; }
}
public class PtplUserApi
{
public string UserId { get; set; }
}
public class TFAlogin
{
public string UserId { get; set; }
public string Password { get; set; }
public string TFASecurityStamp { get; set; }
}
public class PtplUserUpdateApi
{
public string UserId { get; set; }
public string TFAIsEnabled { get; set; }
public string TFASecurityStamp { get; set; }
}
public class TFA_UserDetailsFromApi
{
public string UserId { get; set; }
public string UserName { get; set; }
public string Mobile { get; set; }
public string TFASecurityStamp { get; set; }
public int TFAIsEnabled { get; set; }
public int TFAIsForced { get; set; }
}
}
}
C# (ASP.Net Core)
Login Post Method
Add Properties in Application User Model class
public int IsTwoFactorEnabled { get; set; }
public int IsForceForTwoFactor { get; set; }
public string TFAurl { get; set; }
Login Action Post Method
var res = (dynamic)null;
var _preLoginCheck = await _userManager.FindByNameAsync(loginViewModel.Email);
if (_preLoginCheck == null)
{
result = new
{
Role = "",
Succeeded = false,
Message = "Please enter valid UserId/Password"
};
return Json(result);
}
res = await _signinManager.CheckPasswordSignInAsync(_preLoginCheck, password, false);
if (res.Succeeded && _preLoginCheck.isBlock < 1 && _preLoginCheck.IsLock < 5)
{
if (_preLoginCheck.IsForceForTwoFactor > 0)
{
result = new
{
Succeeded = true,
Message = _preLoginCheck.TFAurl
};
return Json(result);
}
await _userStore.UpdateSerurityStampAsync(loginViewModel.Email);
}
Java script
if (data.succeeded == true) {
location.href = data.message;
}
C# (ASP.NET Core)
Return URL Action for Login
public async Task<IActionResult> TFAReturnLogin(string token)
{
var res = (dynamic)null;
var refereralUrl = HttpContext.Request.Headers["Referer"].ToString();
try
{
if (string.IsNullOrEmpty(token))
{
return Redirect(refereralUrl + "errorLog?log=token is empty or null");
}
var _user = dAL.SelectModel<TFAlogin>("TFA_GetUserDetailsByToken", new { token = token });
if (_user == null)
{
return Redirect(refereralUrl + "errorLog?log=token is empty");
}
if (token == _user.TFASecurityStamp)
{
/////Successfully validate of TFA
///write your login code here
///
#region Login Code
res = await _signinManager.PasswordSignInAsync(_user.UserId, _user.Password, false, lockoutOnFailure: true);
if (res.Succeeded)
{
string Role = _userStore.UpdateLoginInfo(_user.UserId, HttpContext.Connection.RemoteIpAddress.ToString(), "");
_logger.LogInformation("User logged in.");
var _actionName = "Login";
var _PageName = "Login";
SaveAuditTrail(new AuditTrail
{
Action = _actionName,
PageName = _PageName,
UserId = _user.UserId,
Description = _PageName + " has been " + _actionName,
});
return Redirect("/Admin/Dashboard");
}
else
{
return Redirect(refereralUrl + "errorLog?log=Please enter valid UserId/Password");
}
#endregion
}
else
{
return Redirect(refereralUrl + "errorLog?log=token did not macthed of the User");
}
}
catch (Exception ex)
{
return Redirect(refereralUrl + "errorLog?log=Getting some exception: " + ex.Message);
}
return Redirect(refereralUrl + "errorLog?log=Something went wrong");
}
MS Sql Server
Database
Add Three Column in your login table
Alter table [TableName] Add TFASecurityStamp varchar(500)
Alter table [TableName] Add TFAIsEnabled bit
Alter table [TableName] Add TFAIsForced bit
Add Columns in your Login Procedure
Isnull(TFAIsForced,0) as IsForceForTwoFactor,
'https://ddawb.uplive.in/TwoFactorAuth/TFASetup?Ids='+a.UserId+'' TFAurl,
Create Procedures
CREATE Procedure [dbo].[TFA_GetUserDetailsByToken]
@token nvarchar(max)
As
Begin
Select TFASecurityStamp,UserId,Password
from [dbo].[ApplicationUser] Where
TFASecurityStamp=@token
End
Go
CREATE Procedure [dbo].[TFA_GetUserDetails]
@UserId varchar(50)
As
Begin
Select MobileNo as Mobile,UserId, UserName
,TFASecurityStamp,isnull(TFAIsEnabled,0) TFAIsEnabled,isnull(TFAIsForced,0) TFAIsForced
from [dbo].[ApplicationUser] Where
UserId=@UserId
End
Go
Create Procedure [dbo].[TFA_UpdateUserDetails]
@UserId varchar(50),
@TFASecurityStamp varchar(500),
@TFAIsEnabled int
As
Update ApplicationUser set TFAIsEnabled=@TFAIsEnabled, TFASecurityStamp=@TFASecurityStamp
Where UserId=@UserId
Select @@ROWCOUNT
Thank You
Thank you for visiting us.