using System;
using System.Data;
using System.Web;
using System.Web.Configuration;
using System.Web.Security;
using System.Linq;
using System.Xml.Linq;
using Neo.Afx.Utilities;
using DPUruNet;
namespace Neo.Afx.Security
{
///
/// Manages authentication to a .
///
public static class DomainAuthenticationProvider
{
private const int DPFJ_PROBABILITY_ONE = 0x7fffffff;
const string EventSource = "DomainAuthenticationProvider";
//const string ExceptionMessage = "An exception occurred. Please check the log.";
#region AuthenticationMode
///
/// Gets the.
///
public static AuthenticationMode AuthenticationMode
{
get
{
var authType = HttpContext.Current.User.Identity.AuthenticationType;
return (string.IsNullOrEmpty(authType) || authType == "Forms") ? AuthenticationMode.Forms : AuthenticationMode.Windows;
}
}
#endregion
#region DefaultUrl
///
/// Gets the default URL.
///
public static string DefaultUrl
{
get
{
return FormsAuthentication.DefaultUrl.TrimStart('/');
}
}
#endregion
#region Signout
///
/// Sign the user out if the user was signed in using forms authentication.
///
public static void Signout()
{
if(AuthenticationMode == AuthenticationMode.Forms)
{
// Destroy the user's authentication cookie.
FormsAuthentication.SignOut();
// abandon a session and clear the session ID cookie.
HttpContext.Current.Session.Abandon();
HttpContext.Current.Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
}
}
#endregion
#region SetAuthCookie
///
/// Sets the auth cookie.
///
/// The name of the user.
/// true if [persistent]; false otherwise.
/// The data to be stored in the ticket.
public static void SetAuthCookie(string userName, bool persistent, string data = null)
{
// Notice that this cookie will have all the attributes according to
// the ones in the config file setting.
var cookie = FormsAuthentication.GetAuthCookie(userName, persistent);
var ticket = FormsAuthentication.Decrypt(cookie.Value);
// Store the Guid inside the Forms Ticket with all the attributes
// aligned with the config Forms section.
var newticket = new FormsAuthenticationTicket(
ticket.Version,
ticket.Name,
ticket.IssueDate,
ticket.Expiration,
persistent,
data,
ticket.CookiePath);
var encryptedTicket = FormsAuthentication.Encrypt(newticket);
FormsAuthentication.SetAuthCookie(userName, persistent);
}
#endregion
#region GetUserID
///
/// Gets the ID of the current user.
///
/// The ID of the user; -1 if not found.
public static long GetUserID()
{
return GetUserID(HttpContext.Current.User.Identity.Name);
}
///
/// Gets the user ID.
///
/// The name of the user to retrieved.
/// The ID of the user; -1 if not found.
public static long GetUserID(string userName)
{
var membershipProvider = (DomainMembershipProvider)Membership.Provider;
return membershipProvider.GetUserID(userName, AuthenticationMode);
}
#endregion
#region ValidateWindowsUser
///
/// Verifies that the current windows user is authenticated and valid; if so, sets the forms auth cookie.
///
/// true if the windows user is authenticated and valid; false otherwise.
public static bool ValidateWindowsUser()
{
var context = HttpContext.Current;
if(context.User.Identity.IsAuthenticated)
{
var membershipProvider = (DomainMembershipProvider)Membership.Provider;
try
{
var wi = context.Request.LogonUserIdentity;
if(wi != null)
{
var userName = membershipProvider.GetUserName(wi.Name);
if(userName != null)
{
SetAuthCookie(userName, false, "AuthType=Windows");
return true;
}
}
}
// ReSharper disable EmptyGeneralCatchClause
catch
// ReSharper restore EmptyGeneralCatchClause
{
// DomainMembershipProvider writes exception to event log
}
}
return false;
}
#endregion
#region ValidateUser
#region ValidateUser(string userName, string password, bool rememberMe)
///
/// Verifies that the given user name and password are valid.
///
/// The user name to be verified.
/// The password to be verified.
/// true if the authentication cookie should be persisted; false otherwise.
/// true if the user name and password are valid; false otherwise.
public static bool ValidateUser(string userName, string password, bool rememberMe)
{
var membershipProvider = (DomainMembershipProvider)Membership.Provider;
try
{
var token = membershipProvider.GetToken(userName);
if(token != null)
{
var challengeToken = XElement.Parse(token);
var credentials = SecurePassword.CreateSecureCredentials(challengeToken, password);
if(Membership.ValidateUser(userName, credentials))
{
SetAuthCookie(userName, rememberMe, "AuthType=Forms");
return true;
}
}
}
// ReSharper disable EmptyGeneralCatchClause
catch
// ReSharper restore EmptyGeneralCatchClause
{
// DomainMembershipProvider writes exception to event log
}
return false;
}
#endregion
#region ValidateUser(string fingerPrint, bool rememberMe, ref string userName)
///
/// Verifies that the given fingerprint is valid
///
/// The fingerprint to be verified.
/// true if the authentication cookie should be persisted; false otherwise.
/// true if the fingerprint valid; false otherwise.
public static bool ValidateUser(string fingerPrint, bool rememberMe, ref string userName)
{
return ValidateUser(fingerPrint, rememberMe, 0, ref userName);
}
#endregion
#region ValidateUser(string fingerPrint, bool rememberMe, long userID, ref string userName)
///
/// Verifies that the given fingerprint is valid
///
/// The fingerprint to be verified.
/// true if the authentication cookie should be persisted; false otherwise.
/// true if the fingerprint valid; false otherwise.
public static bool ValidateUser(string fingerPrint, bool rememberMe, long userID, ref string userName)
{
var validUserFound = false;
int thresholdScore = DPFJ_PROBABILITY_ONE * 1 / 100000;
var membershipProvider = (DomainMembershipProvider)Membership.Provider;
try
{
var fingerprintBytes = Convert.FromBase64String(fingerPrint);
Fmd fmd = new Fmd(fingerprintBytes, (int)Constants.Formats.Fmd.DP_VERIFICATION, "1.0.0");
using (var fingerPrintTable = membershipProvider.GetUserFingerprintTemplates())
{
if (fingerPrintTable.Rows.Count > 0)
{
//If a userid was provided, check if you can find the id in the list and check that fingerprint first
if (userID > 0)
{
var r = fingerPrintTable.AsEnumerable().Where(a => a.Field("UserID") == userID).FirstOrDefault();
if (r != null)
{
Fmd[] fmds = new Fmd[1];
fmds[0] = new Fmd((Byte[])r.Field("FingerprintTemplate"), (int)Constants.Formats.Fmd.DP_REGISTRATION, "1.0.0");
IdentifyResult identifyResult = Comparison.Identify(fmd, 0, fmds, thresholdScore, 2);
if (identifyResult.ResultCode == Constants.ResultCode.DP_SUCCESS)
{
if (identifyResult.Indexes.Length == 1)
{
SetAuthCookie(r.Field("Email").ToString(), rememberMe, "AuthType=Forms");
userName = r.Field("Email").ToString();
validUserFound = true;
}
}
}
}
//if the specified user was not found, check all the other users
if (!validUserFound)
{
foreach (DataRow r in fingerPrintTable.Rows)
{
Fmd[] fmds = new Fmd[1];
fmds[0] = new Fmd((Byte[])r.Field("FingerprintTemplate"), (int)Constants.Formats.Fmd.DP_REGISTRATION, "1.0.0");
IdentifyResult identifyResult = Comparison.Identify(fmd, 0, fmds, thresholdScore, 2);
if (identifyResult.ResultCode == Constants.ResultCode.DP_SUCCESS)
{
if (identifyResult.Indexes.Length == 1)
{
SetAuthCookie(r.Field("Email").ToString(), rememberMe, "AuthType=Forms");
userName = r.Field("Email").ToString();
validUserFound = true;
break;
}
}
}
}
}
}
}
// ReSharper disable EmptyGeneralCatchClause
catch (Exception ex)
// ReSharper restore EmptyGeneralCatchClause
{
// DomainMembershipProvider writes exception to event log
}
return validUserFound;
}
#endregion
#endregion
#region GetResetQuestion
///
/// Gets the password question for the user.
///
/// The user name to be queried.
/// The password question for the user.
public static string GetResetQuestion(string userName)
{
var membershipProvider = (DomainMembershipProvider)Membership.Provider;
return membershipProvider.GetPasswordQuestion(userName);
}
#endregion
#region ResetPassword
///
/// Resets a user's password to a new, automatically generated password.
///
/// The user to reset the password for.
/// The password question for the specified user.
/// The password answer for the specified user.
/// The new password for the specified user.
public static bool ResetPassword(string userName, string question, string answer)
{
var membershipProvider = (DomainMembershipProvider)Membership.Provider;
try
{
var token = membershipProvider.GetResetToken(userName);
if(token != null)
{
var challengeToken = XElement.Parse(token);
if(challengeToken.Value == question)
{
var credentials = SecurePassword.CreateSecureCredentials(challengeToken, answer);
membershipProvider.ResetPassword(userName, credentials);
return true;
}
}
}
// ReSharper disable EmptyGeneralCatchClause
catch
// ReSharper restore EmptyGeneralCatchClause
{
// DomainMembershipProvider writes exception to event log
}
return false;
}
#endregion
}
}