Identity 2.0 Invalid Token when Confirming Email - c#

On my comfirm page I get an invalid token error on manager.ConfirmEmail(userID, code)
protected void Page_Load(object sender, EventArgs e)
{
string code = IdentityHelper.GetCodeFromRequest(Request);
string userId = IdentityHelper.GetUserIdFromRequest(Request);
if (code != null && userId != null)
{
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
var result = manager.ConfirmEmail(userId, code);
if (result.Succeeded)
{
successPanel.Visible = true;
return;
}
}
successPanel.Visible = false;
errorPanel.Visible = true;
}
Here is the code to register the user, everything works and the email sends:
protected void CreateUser_Click(object sender, EventArgs e)
{
var currentApplicationId = GetApplicationID();
var manager = new UserManager();
User user = new User() { UserName = Email.Text, ApplicationId = currentApplicationId, LoweredUserName = Email.Text.ToLower(), Email=Email.Text,LoweredEmail=Email.Text.ToLower() };
user.IsApproved = true;
IdentityResult result = manager.Create(user, Password.Text);
if (result.Succeeded)
{
var provider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("SynergyWebApp2015");
//UserManager<User> userManager = new UserManager<User>(new Microsoft.AspNet.Identity.EntityFramework.UserStore<User>());
//userManager.UserTokenProvider = new Microsoft.AspNet.Identity.Owin.DataProtectorTokenProvider<User>(provider.Create(user.Id));
manager.UserTokenProvider = new Microsoft.AspNet.Identity.Owin.DataProtectorTokenProvider<User>(provider.Create("ConfirmUser"));
// -----------------------EMAIL----------------------------
string code = manager.GenerateEmailConfirmationToken(user.Id);
string callbackUrl = IdentityHelper.GetUserConfirmationRedirectUrl(code, user.Id, Request);
Context.GetOwinContext().GetUserManager<ApplicationUserManager>().SendEmail(user.Id, "Confirm your account", "Please confirm your account by clicking here.");
///--------------------------------------------------------
ErrorMessage.Text = "An email has been sent to your account. Please view the email and confirm your account to complete the registration process.";
}
else
{
ErrorMessage.Text = result.Errors.FirstOrDefault();
}
}
private Guid GetApplicationID()
{
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
{
string queryString = "SELECT ApplicationId from aspnet_Applications WHERE ApplicationName = '/'"; //Set application name as in database
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
var reader = command.ExecuteReader();
while (reader.Read())
{
return reader.GetGuid(0);
}
return Guid.NewGuid();
}
}
Here is my User Manager Class
public class UserManager : UserManager<User>
{
public UserManager()
: base(new UserStore<User>(new ApplicationDbContext()))
{
/* var provider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("Sample");
UserManager<User> userManager = new UserManager<User>(new UserStore<User>());
userManager.UserTokenProvider = new Microsoft.AspNet.Identity.Owin.DataProtectorTokenProvider<User>(provider.Create("EmailConfirmation"));
*/
this.PasswordHasher = new SQLPasswordHasher();
}
}
public class SQLPasswordHasher : PasswordHasher
{
public override string HashPassword(string password)
{
return base.HashPassword(password);
}
public override PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword)
{
string[] passwordProperties = hashedPassword.Split('|');
if (passwordProperties.Length != 3)
{
return base.VerifyHashedPassword(hashedPassword, providedPassword);
}
else
{
string passwordHash = passwordProperties[0];
int passwordformat = 1;
string salt = passwordProperties[2];
if (String.Equals(EncryptPassword(providedPassword, passwordformat, salt), passwordHash, StringComparison.CurrentCultureIgnoreCase))
{
return PasswordVerificationResult.SuccessRehashNeeded;
}
else
{
return PasswordVerificationResult.Failed;
}
}
}
//This is copied from the existing SQL providers and is provided only for back-compat.
private string EncryptPassword(string pass, int passwordFormat, string salt)
{
if (passwordFormat == 0) // MembershipPasswordFormat.Clear
return pass;
byte[] bIn = Encoding.Unicode.GetBytes(pass);
byte[] bSalt = Convert.FromBase64String(salt);
byte[] bRet = null;
if (passwordFormat == 1)
{ // MembershipPasswordFormat.Hashed
HashAlgorithm hm = HashAlgorithm.Create("SHA1");
if (hm is KeyedHashAlgorithm)
{
KeyedHashAlgorithm kha = (KeyedHashAlgorithm)hm;
if (kha.Key.Length == bSalt.Length)
{
kha.Key = bSalt;
}
else if (kha.Key.Length < bSalt.Length)
{
byte[] bKey = new byte[kha.Key.Length];
Buffer.BlockCopy(bSalt, 0, bKey, 0, bKey.Length);
kha.Key = bKey;
}
else
{
byte[] bKey = new byte[kha.Key.Length];
for (int iter = 0; iter < bKey.Length; )
{
int len = Math.Min(bSalt.Length, bKey.Length - iter);
Buffer.BlockCopy(bSalt, 0, bKey, iter, len);
iter += len;
}
kha.Key = bKey;
}
bRet = kha.ComputeHash(bIn);
}
else
{
byte[] bAll = new byte[bSalt.Length + bIn.Length];
Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length);
Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length);
bRet = hm.ComputeHash(bAll);
}
}
return Convert.ToBase64String(bRet);
}
}
public static class IdentityHelper
{
// Used for XSRF when linking external logins
public const string XsrfKey = "XsrfId";
public static void SignIn(UserManager manager, User user, bool isPersistent)
{
IAuthenticationManager authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
authenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = manager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}
public const string ProviderNameKey = "providerName";
public static string GetProviderNameFromRequest(HttpRequest request)
{
return request[ProviderNameKey];
}
public static string GetExternalLoginRedirectUrl(string accountProvider)
{
return "/IdentityAccount/RegisterExternalLogin.aspx?" + ProviderNameKey + "=" + accountProvider;
}
private static bool IsLocalUrl(string url)
{
return !string.IsNullOrEmpty(url) && ((url[0] == '/' && (url.Length == 1 || (url[1] != '/' && url[1] != '\\'))) || (url.Length > 1 && url[0] == '~' && url[1] == '/'));
}
public static void RedirectToReturnUrl(string returnUrl, HttpResponse response)
{
if (!String.IsNullOrEmpty(returnUrl) && IsLocalUrl(returnUrl))
{
response.Redirect(returnUrl);
}
else
{
response.Redirect("~/");
}
}
}

I fixed this.
string code = manager.GenerateEmailConfirmationToken(user.Id);
Needed to be:
string code = Context.GetOwinContext().GetUserManager<ApplicationUserManager>().GenerateEmailConfirmationToken(user.Id);
This answer will be useful to anyone switching from SQL Membership to Identity 2.0 using the .net article on migration.

Related

How to extend LazyCache with Redis Cache for asp.net core 3.1 application?

I have asp.net core 3.1 web api project which leverages Azure SQL database as its data storage option. At present I am also using Azure Redis Cache to improve performance of the application.
Here goes the code details :
ICacheProvider.cs:
public interface ICacheProvider
{
IList<string> GetKeys();
IList<string> GetKeys(string strGroup);
T Get<T>(string strKey, string strGroup = "");
bool Set(string strKey, object objData, string strGroup = "", int? intMinutes = null);
bool Remove(string strKey, string strGroup = "");
bool RemoveGroup(string strGroup);
bool ClearCache();
Task<bool> ClearCacheAsync();
}
CacheProvider.cs
public class CacheProvider : ICacheProvider
{
private static readonly int ExpiryMinutes = ConfigManager.Get(CacheExpiryMinutes, CacheExpiryMinutes);
private static Lazy<ConnectionMultiplexer> _objCacheConn = CreateConnection();
private static Lazy<ConnectionMultiplexer> CreateConnection()
{
return new Lazy<ConnectionMultiplexer>(() =>
{
string conn = ConfigManager.Get(RedisConnString);
return ConnectionMultiplexer.Connect(conn);
});
}
private ConnectionMultiplexer Connection
{
get
{
return _objCacheConn.Value;
}
}
private IDatabase GetDatabase()
{
return Connection.GetDatabase();
}
private EndPoint[] GetEndPoints()
{
return Connection.GetEndPoints();
}
private IServer GetServer()
{
var objEndpoint = GetEndPoints().First();
return Connection.GetServer(objEndpoint);
}
public IList<string> GetKeys()
{
return GetKeys("*");
}
public IList<string> GetKeys(string strGroup)
{
var lstKeys = new List<string>();
try
{
var objServer = GetServer();
if (objServer != null)
{
var strPattern = strGroup + ":*";
var objRedisKeys = objServer.Keys(pattern: strPattern);
var objLst = objRedisKeys.GetEnumerator();
while (objLst.MoveNext())
{
lstKeys.Add(objLst.Current.ToString());
}
}
}
catch (Exception)
{
lstKeys = new List<string>();
}
return lstKeys;
}
public T Get<T>(string strKey, string strGroup = "")
{
T objData = default(T);
try
{
var objCache = GetDatabase();
if (!strKey.IsEmpty() && objCache != null)
{
strKey = (strGroup.IsEmpty() ? C.CacheGroups.General : strGroup) + ":" + strKey;
var strData = objCache.StringGet(strKey).ToString();
if (!strData.IsEmpty())
{
objData = JsonConvert.DeserializeObject<T>(strData);
}
}
}
catch (Exception)
{
objData = default(T);
}
return objData;
}
public bool Set(string strKey, object objData, string strGroup = "", int? intMinutes = null)
{
bool blnSuccess = false;
try
{
var objCache = GetDatabase();
if (!strKey.IsEmpty() && objData != null && objCache != null)
{
intMinutes = intMinutes ?? ExpiryMinutes;
strKey = (strGroup.IsEmpty() ? C.CacheGroups.General : strGroup) + ":" + strKey;
var strData = JsonConvert.SerializeObject(objData);
var tsExpiry = new TimeSpan(0, intMinutes.Value, 0);
blnSuccess = objCache.StringSet(strKey, strData, tsExpiry);
}
}
catch (Exception)
{
blnSuccess = false;
}
return blnSuccess;
}
public bool Remove(string strKey, string strGroup = "")
{
bool blnSuccess = false;
try
{
var objCache = GetDatabase();
if (!strKey.IsEmpty() && objCache != null)
{
strKey = (strGroup.IsEmpty() ? C.CacheGroups.General : strGroup) + ":" + strKey;
blnSuccess = objCache.KeyDelete(strKey);
}
}
catch (Exception)
{
blnSuccess = false;
}
return blnSuccess;
}
public bool RemoveGroup(string strGroup)
{
bool blnSuccess = false;
try
{
var lstKeys = GetKeys(strGroup);
var objCache = GetDatabase();
if (lstKeys.Count > 0 && objCache != null)
{
foreach (var strKey in lstKeys)
{
objCache.KeyDelete(strKey);
}
blnSuccess = true;
}
}
catch (Exception)
{
blnSuccess = false;
}
return blnSuccess;
}
public bool ClearCache()
{
bool blnSuccess = false;
try
{
var objServer = GetServer();
if (objServer != null)
{
objServer.FlushAllDatabases();
blnSuccess = true;
}
}
catch (Exception)
{
blnSuccess = false;
}
return blnSuccess;
}
public async Task<bool> ClearCacheAsync()
{
// Get server details
var server = GetServer();
if (server is null)
return false;
// Flush All Databases
await server.FlushAllDatabasesAsync();
return true;
}
}
I am consuming the above CacheProvider in my code as mentioned below :
private async Task<IReadOnlyList<TestInfo>> GetDataAsync(int Id1, int Id2, int Id3, string cacheKey)
{
var data = _cacheProvider.Get<IReadOnlyList<TestInfo>>(cacheKey, TestCacheGroup);
if (data is null)
{
data = await _test.GetSampleDataAsync(Id1, Id2, Id3);
_cacheProvider.Set(cacheKey, data, TestCacheGroup, Defaults.CacheExpiryMinutes);
}
return data;
}
LazyCache by default uses MemoryCache under the hood. I came through documentation that LazyCache can be extended to swap out to redis or casandra at a later time but keep the same code and API.
Can anyone help me here with some code sample which will serve as a reference for my implementation

Exception of type 'Braintree.Exceptions.AuthenticationException' and Private key is seen as "PrivateKey"

Check out Controller
public class CheckoutsController : Controller
{
public IBraintreeConfiguration config = new BraintreeConfiguration();
public static readonly TransactionStatus[] transactionSuccessStatuses = {
TransactionStatus.AUTHORIZED,
TransactionStatus.AUTHORIZING,
TransactionStatus.SETTLED,
TransactionStatus.SETTLING,
TransactionStatus.SETTLEMENT_CONFIRMED,
TransactionStatus.SETTLEMENT_PENDING,
TransactionStatus.SUBMITTED_FOR_SETTLEMENT
};
public ActionResult New()
{
var gateway = config.GetGateway();
This is the line that is triggering the error ('Braintree.Exceptions.AuthenticationException')
var clientToken = gateway.ClientToken.generate();
ViewBag.ClientToken = clientToken;
return View();
}
public ActionResult Create()
{
var gateway = config.GetGateway();
Decimal amount;
try
{
amount = Convert.ToDecimal(Request["amount"]);
}
catch (FormatException e)
{
TempData["Flash"] = "Error: 81503: Amount is an invalid format.";
return RedirectToAction("New");
}
var nonce = Request["payment_method_nonce"];
var request = new TransactionRequest
{
Amount = amount,
PaymentMethodNonce = nonce,
Options = new TransactionOptionsRequest
{
SubmitForSettlement = true
}
};
Result<Transaction> result = gateway.Transaction.Sale(request);
if (result.IsSuccess())
{
Transaction transaction = result.Target;
return RedirectToAction("Show", new { id = transaction.Id });
}
else if (result.Transaction != null)
{
return RedirectToAction("Show", new { id = result.Transaction.Id });
}
else
{
string errorMessages = "";
foreach (ValidationError error in result.Errors.DeepAll())
{
errorMessages += "Error: " + (int)error.Code + " - " + error.Message + "\n";
}
TempData["Flash"] = errorMessages;
return RedirectToAction("New");
}
}
public ActionResult Show(String id)
{
var gateway = config.GetGateway();
Transaction transaction = gateway.Transaction.Find(id);
if (transactionSuccessStatuses.Contains(transaction.Status))
{
TempData["header"] = "Sweet Success!";
TempData["icon"] = "success";
TempData["message"] = "Your test transaction has been successfully processed. See the Braintree API response and try again.";
}
else
{
TempData["header"] = "Transaction Failed";
TempData["icon"] = "fail";
TempData["message"] = "Your test transaction has a status of " + transaction.Status + ". See the Braintree API response and try again.";
};
ViewBag.Transaction = transaction;
return View();
}
}
BrainTree Configuration
public class BraintreeConfiguration : IBraintreeConfiguration
{
public string Environment { get; set; }
public string MerchantId { get; set; }
public string PublicKey { get; set; }
public string PrivateKey { get; set; }
private IBraintreeGateway BraintreeGateway { get; set; }
public IBraintreeGateway CreateGateway()
{
Environment = System.Environment.GetEnvironmentVariable("BraintreeEnvironment");
MerchantId = System.Environment.GetEnvironmentVariable("BraintreeMerchantId");
PublicKey = System.Environment.GetEnvironmentVariable("BraintreePublicKey");
PrivateKey = System.Environment.GetEnvironmentVariable("BraintreePrivateKey");
if (MerchantId == null || PublicKey == null || PrivateKey == null)
{
Environment = GetConfigurationSetting("BraintreeEnvironment");
MerchantId = GetConfigurationSetting("BraintreeMerchantId");
PublicKey = GetConfigurationSetting("BraintreePublicKey");
PrivateKey = GetConfigurationSetting("BraintreePrivateKey");
}
return new BraintreeGateway(Environment, MerchantId, PublicKey, PrivateKey);
}
public string GetConfigurationSetting(string setting)
{
//watch this
MerchantId = "**************";
PublicKey = "***************";
The merchant id and public Key are being assigned their correct values but the private Key is being assigned as "PrivateKey"
PrivateKey = "*************************";
return ConfigurationManager.AppSettings[setting];
}
public IBraintreeGateway GetGateway()
{
if (BraintreeGateway == null)
{
BraintreeGateway = CreateGateway();
}
return BraintreeGateway;
}
}

C# - Look up direct reports in active directory

I am using System.DirectoryServices.AccountManagement to manage my login user account.
I am able to get information for login user, but not able to get direct reports user id based on manager.
var context = new PrincipalContext(ContextType.Domain);
var principal = UserPrincipal.FindByIdentity(context, User.Identity.Name);
I have refer to this link: C# - Look up a users manager in active directory
But still didn't get any clue. Anyone can help me on this?
I managed to figure out the directory property for direct reports("directReports").
Just to add a new directory property as below:
// Create the "Direct Report" property.
[DirectoryProperty("directReports")]
public List<string> DirectReports
{
get
{
var directReportsName = new List<string>();
if (ExtensionGet("directReports").Length == 0)
return directReportsName;
for (int i = 0; i < ExtensionGet("directReports").Length; i++)
{
string userString = (string)ExtensionGet("directReports")[i];
//example of userString = CN=name,OU=Users,OU=department,OU=AP,OU=Software,DC=company,DC=priv,DC=company,DC=com
//split by comma
var tempCN = userString.Split(',').First();
var tempName = tempCN.Split('=');
var userName= tempName[1];
directReportsAlias.Add(userName);
}
return directReportsName;
}
}
I have designed class for active directory search.
This class support.
Search Employee By Same Account Name
Search Employee By Employee Id
Search Employee By Employee Code
Search Employee By Employee Email
Search Employee Manage
Search Team Member
CLASS CODE
using System;
using System.Collections.Generic;
using System.Text;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
namespace UAT.COMMON
{
#region RefranceHelpers
/*
//https://www.c-sharpcorner.com/article/active-directory-and-net/
//https://ianatkinson.net/computing/adcsharp.htm
//https://ianatkinson.net/computing/adcsharp.htm
*/
#endregion
public enum SearchBy
{
StartNTID=0,
}
public class ManageDirectoryServices : IDisposable
{
public ContextType contextType = ContextType.Domain;
public PrincipalContext Context { get; protected set; }
public UserPrincipal User { get; protected set; }
public UserPrincipal Manager { get; protected set; }
public bool IsManager { get; protected set; }
public List<UserPrincipal> DirectReports { get; protected set; }
public class AuthenticationResult
{
public AuthenticationResult()
{
IdentityError = new List<IdentityError>();
IsSuccess = IdentityError.Count > 0;
}
public List<IdentityError> IdentityError { get; private set; }
public String RoleName { get; private set; }
public Boolean IsSuccess { get; set; }
public ManageDirectoryServices Context { get; set; }
}
public ManageDirectoryServices()
{
Context = new PrincipalContext(contextType);
DirectReports = new List<UserPrincipal>();
}
public ManageDirectoryServices(string ntid)
{
Context = new PrincipalContext(contextType);
DirectReports = new List<UserPrincipal>();
GetEmployeeByNTID(NormalizeNTID(ntid));
}
/// <summary>
///
/// </summary>
/// <param name="ntid">This is SamAccountName</param>
/// <returns></returns>
public ManageDirectoryServices GetEmployeeByNTID(string ntid)
{
if (string.IsNullOrWhiteSpace(ntid)) return null;
UserPrincipal searchTemplate = new UserPrincipal(Context)
{
SamAccountName = ntid
};
PrincipalSearcher ps = new PrincipalSearcher(searchTemplate);
User = (UserPrincipal)ps.FindOne();
return this;
}
public ManageDirectoryServices GetEmployee(string strSearch,string prop)
{
if (string.IsNullOrWhiteSpace(strSearch)) return this;
if (string.IsNullOrWhiteSpace(prop)) return this;
DirectorySearcher search = new DirectorySearcher();
search.Filter = String.Format("(cn={0})", strSearch);
search.PropertiesToLoad.Add(prop);
var result = search.FindAll();
if (result != null)
{
int directReports = result.Count; //result.Properties["displayname"].Count;
if (directReports < 0) return null;
for (int counter = 0; counter < directReports; counter++)
{
var user = (string)result[counter].Properties["givenname"][counter];
var reporte = UserPrincipal.FindByIdentity(Context, IdentityType.DistinguishedName, user);
this.DirectReports.Add(reporte);
IsManager = true;
}
return this;
}
return null;
}
public ManageDirectoryServices GetEmployee(UserPrincipal searchTemplate)
{
if (searchTemplate == null) return null;
PrincipalSearcher ps = new PrincipalSearcher(searchTemplate);
User = (UserPrincipal)ps.FindOne();
return this;
}
/// <summary>
///
/// </summary>
/// <param name="NTID">This is SamAccountName</param>
/// <returns></returns>
public bool IsUserExist(string NTID)
{
var data = GetEmployeeByNTID(NormalizeNTID(NTID));
return !string.IsNullOrWhiteSpace(data?.User?.SamAccountName);
}
public bool IsUserExist()
{
var data = User;
return !string.IsNullOrWhiteSpace(data?.SamAccountName);
}
public ManageDirectoryServices GetEmployeeByEmail(string email)
{
if (string.IsNullOrWhiteSpace(email)) return null;
UserPrincipal searchTemplate = new UserPrincipal(Context)
{
EmailAddress = email
};
PrincipalSearcher ps = new PrincipalSearcher(searchTemplate);
User = (UserPrincipal)ps.FindOne();
return this;
}
public ManageDirectoryServices GetEmployeeByEmpId(string employeeId)
{
if (string.IsNullOrWhiteSpace(employeeId)) return null;
UserPrincipal searchTemplate = new UserPrincipal(Context)
{
EmployeeId = employeeId
};
PrincipalSearcher ps = new PrincipalSearcher(searchTemplate);
User = (UserPrincipal)ps.FindOne();
return this;
}
public ManageDirectoryServices GetManager()
{
if (this.User == null) return null;
DirectoryEntry ManagerDE = this.User.GetUnderlyingObject() as DirectoryEntry;
var manager = ManagerDE.Properties["manager"].Value.ToString();
UserPrincipal oManager = UserPrincipal.FindByIdentity(Context, IdentityType.DistinguishedName, manager);
this.Manager = oManager;
return this;
}
public ManageDirectoryServices GetDirectReports()
{
if (this.User == null) return this;
DirectorySearcher search = new DirectorySearcher();
search.Filter = String.Format("(cn={0})", this.User.SamAccountName);
search.PropertiesToLoad.Add("directReports");
SearchResult result = search.FindOne();
if (result != null)
{
int directReports = result.Properties["directReports"].Count;
if (directReports < 0) return null;
for (int counter = 0; counter < directReports; counter++)
{
var user = (string)result.Properties["directReports"][counter];
var reporte = UserPrincipal.FindByIdentity(Context, IdentityType.DistinguishedName, user);
this.DirectReports.Add(reporte);
IsManager = true;
}
return this;
}
return null;
}
public string NormalizeNTID(string Id)
{
if (string.IsNullOrWhiteSpace(Id)) return "";
return Id.Trim().ToUpper().Replace(#"\", "")
.Replace("\\", "")
.Replace("/", "")
.Replace("//", "")
.Replace("MS", "")
.Replace("MS//", "")
.Replace("MS\\", "");
}
public AuthenticationResult SignIn(string ntid, string password)
{
var NormalizeNTID = this.NormalizeNTID(ntid);
bool IsAuthenticated = false;
IdentityError identityError = new IdentityError();
ManageDirectoryServices context = null;
AuthenticationResult authenticationResult = new AuthenticationResult();
var IsSuccess = Context.ValidateCredentials(NormalizeNTID, password, ContextOptions.Negotiate);
context = GetEmployeeByNTID(NormalizeNTID);
if (IsSuccess)
{
if (context.User != null)
{
IsAuthenticated = true;
this.User = context.User;
authenticationResult.Context = context;
authenticationResult.IsSuccess = true;
}
}
else
{
if (!IsAuthenticated || User == null)
{
authenticationResult.IdentityError.Add(new IdentityError
{
Code = "InCorrectUserAndPassword",
Description = "Username or Password is not correct"
});
}
if (context.User.IsAccountLockedOut())
{
authenticationResult.IdentityError.Add(new IdentityError
{
Code = "YourAccountIsLocked",
Description = "Your account is locked."
});
}
if (context.User.Enabled.HasValue && User.Enabled.Value == false)
{
authenticationResult.IdentityError.Add(identityError = new IdentityError
{
Code = "YourAccountIsDisabled",
Description = "Your account is disabled"
});
}
else
{
authenticationResult.IdentityError.Add(new IdentityError
{
Code = "InvalidLogin",
Description = "In valid login!! Please try again"
});
}
}
return authenticationResult;
}
#region ************Async Envelope**************
public async Task<ManageDirectoryServices> GetEmployeeByNTIDAsync(string ntid)
{
return await Task.Run(() => GetEmployeeByNTID(ntid));
}
public async Task<ManageDirectoryServices> GetEmployeeByEmailAsync(string email)
{
return await Task.Run(() => GetEmployeeByEmail(email));
}
public async Task<ManageDirectoryServices> GetEmployeeByEmpIdAsync(string employeeId)
{
return await Task.Run(() => GetEmployeeByEmpId(employeeId));
}
public async Task<ManageDirectoryServices> GetManagerAsync()
{
return await Task.Run(() => GetManager());
}
public async Task<ManageDirectoryServices> GetDirectReportsAsync()
{
return await Task.Run(() => GetDirectReports());
}
public async Task<AuthenticationResult> SignInAsync(string ntid, string password)
{
return await Task.Run(() => SignIn(ntid, password));
}
#endregion
public void Dispose()
{
this.Dispose();
GC.Collect();
}
}
}
How To Use
[TestMethod]
public void ContractorInitialsSuccess()
{
ManageDirectoryServices manageDirectoryServices = new ManageDirectoryServices(MSID);
var context = manageDirectoryServices.User;
Assert.AreEqual(MSID, context.SamAccountName);
}
[TestMethod]
public void SignInSuccess()
{
ManageDirectoryServices manageDirectoryServices = new ManageDirectoryServices();
var context = manageDirectoryServices.SignIn(MSID,MSPASSWORD);
Assert.AreEqual(EMAIL, context.Context.User.EmailAddress);
}
[TestMethod]
public void GetEmployeeByNTIDSuccess()
{
ManageDirectoryServices manageDirectoryServices = new ManageDirectoryServices();
var context = manageDirectoryServices.GetEmployeeByNTID(MSID);
Assert.AreEqual(MSID, context.User.SamAccountName);
}
[TestMethod]
public void GetManagerSuccess()
{
ManageDirectoryServices manageDirectoryServices = new ManageDirectoryServices();
var context = manageDirectoryServices.GetEmployeeByNTID(MSID);
var manager = context.GetManager();
Assert.AreEqual(MANAGER_NTID, context.Manager.SamAccountName);
}
[TestMethod]
public void GetReportesSuccess()
{
ManageDirectoryServices manageDirectoryServices = new ManageDirectoryServices();
var context = manageDirectoryServices.GetEmployeeByNTID(MSID);
var repcontext = context.GetDirectReports();
var flag = repcontext.DirectReports.Count > 0 ? true : false;
Assert.AreEqual(true, flag);
}
[TestMethod]
public void GetEmployeeByEmailSuccess()
{
ManageDirectoryServices manageDirectoryServices = new ManageDirectoryServices();
var context = manageDirectoryServices.GetEmployeeByEmail(EMAIL);
Assert.AreEqual(EMAIL, context.User.EmailAddress);
}
[TestMethod]
public void GetEmployeeByEmployeeIdSuccess()
{
ManageDirectoryServices manageDirectoryServices = new ManageDirectoryServices();
var context = manageDirectoryServices.GetEmployeeByEmpId(EMPLOYEEID);
Assert.AreEqual(EMPLOYEEID, context.User.EmployeeId);
}
[TestMethod]
public void IsUserExistSuccess()
{
ManageDirectoryServices manageDirectoryServices = new ManageDirectoryServices();
var IsExist = manageDirectoryServices.IsUserExist(MSID);
Assert.AreEqual(true, IsExist);
}
[TestMethod]
public void IsUserExistFail()
{
ManageDirectoryServices manageDirectoryServices = new ManageDirectoryServices();
var IsExist = manageDirectoryServices.IsUserExist("invalidid");
Assert.AreEqual(false, IsExist);
}
[TestMethod]
public void GetEmployeeSuccess()
{
ManageDirectoryServices manageDirectoryServices = new ManageDirectoryServices();
var searchTemplate = new System.DirectoryServices.AccountManagement.UserPrincipal(manageDirectoryServices.Context) {
SamAccountName= MSID,
EmailAddress=EMAIL,
EmployeeId=EMPLOYEEID
};
var context = manageDirectoryServices.GetEmployee(searchTemplate);
Assert.AreEqual(MSID, context.User.SamAccountName);
}
[TestMethod]
public void GetEmployeeNameSuccess0()
{
ManageDirectoryServices manageDirectoryServices = new ManageDirectoryServices();
var repcontext = manageDirectoryServices.GetEmployee("abhishek", "givenname");
var flag = repcontext.DirectReports.Count > 0 ? true : false;
Assert.AreEqual(true, flag);
}
[TestMethod]
public void GetEmployeeNameSuccess1()
{
ManageDirectoryServices manageDirectoryServices = new ManageDirectoryServices();
var repcontext = manageDirectoryServices.GetEmployee("abhishek", "name");
var flag = repcontext.DirectReports.Count > 0 ? true : false;
Assert.AreEqual(true, flag);
}
[TestMethod]
public void GetEmployeeNameSuccess2()
{
ManageDirectoryServices manageDirectoryServices = new ManageDirectoryServices();
var repcontext = manageDirectoryServices.GetEmployee("abhishek", "displayname");
var flag = repcontext.DirectReports.Count > 0 ? true : false;
Assert.AreEqual(true, flag);
}

How use custom IPasswordHasher?

I implements IPasswordHasher
public class MyPasswordHasher : IPasswordHasher
{
public string HashPassword(string password)
{
using (SHA256 mySHA256 = SHA256Managed.Create())
{
byte[] hash = mySHA256.ComputeHash(Encoding.UTF8.GetBytes(password.ToString()));
StringBuilder hashSB = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
hashSB.Append(hash[i].ToString("x2"));
}
return hashSB.ToString();
}
}
public PasswordVerificationResult VerifyHashedPassword(
string hashedPassword, string providedPassword)
{
if (hashedPassword == HashPassword(providedPassword))
return PasswordVerificationResult.Success;
else
return PasswordVerificationResult.Failed;
}
}
I write in IdentityConfig
manager.PasswordHasher = new MyPasswordHasher();
but var user = await UserManager.FindAsync(model.Email, model.Password); in AccountController/Login do not use MyPasswordHaser.
How can I use it in Identity 2.1?
You have to plug it into the UserManager:
public class AppUserManager : UserManager<AppUser, int>
{
public AppUserManager(AppUserStore a_store)
: base(a_store)
{
_container = a_container;
_emailService = _container.GetInstance<IEmailService>();
PasswordHasher = new AppPasswordHasher();
}
}
Use:
PasswordHasher = new MyPasswordHasher();
in UserManager ctor!

WP8 HttpClient.PostAsync never returns result

I have a Windows Phone 8 app where I am calling await HttpClient.PostAsync and it never returns a result. It just sits there and hangs. If I run the exact same code from a console app, it returns the result almost immediately. All of the code doing the work resides in a portable class library. I would appreciate any help you may be able to give. All of the other issues I have found on this state to use await client.PostAsync, which I am already doing.
The code in my class library is as such:
public class Authenticator
{
private const string ApiBaseUrl = "http://api.fitbit.com";
private const string Callback = "http://myCallbackUrlHere";
private const string SignatureMethod = "HMAC-SHA1";
private const string OauthVersion = "1.0";
private const string ConsumerKey = "myConsumerKey";
private const string ConsumerSecret = "myConsumerSecret";
private const string RequestTokenUrl = "http://api.fitbit.com/oauth/request_token";
private const string AccessTokenUrl = "http://api.fitbit.com/oauth/access_token";
private const string AuthorizeUrl = "http://www.fitbit.com/oauth/authorize";
private string requestToken;
private string requestTokenSecret;
public string GetAuthUrlToken()
{
return GenerateAuthUrlToken().Result;
}
private async Task<string> GenerateAuthUrlToken()
{
var httpClient = new HttpClient { BaseAddress = new Uri(ApiBaseUrl) };
var timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0);
var oauthTimestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString(CultureInfo.InvariantCulture);
var oauthNonce = DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture);
var authHeaderValue = string.Format(
"oauth_callback=\"{0}\",oauth_consumer_key=\"{1}\",oauth_nonce=\"{2}\"," +
"oauth_signature=\"{3}\",oauth_signature_method=\"{4}\"," +
"oauth_timestamp=\"{5}\",oauth_version=\"{6}\"",
Uri.EscapeDataString(Callback),
Uri.EscapeDataString(ConsumerKey),
Uri.EscapeDataString(oauthNonce),
Uri.EscapeDataString(this.CreateSignature(RequestTokenUrl, oauthNonce, oauthTimestamp, Callback)),
Uri.EscapeDataString(SignatureMethod),
Uri.EscapeDataString(oauthTimestamp),
Uri.EscapeDataString(OauthVersion));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"OAuth",
authHeaderValue);
var content = new StringContent(string.Empty);
var response = await httpClient.PostAsync(RequestTokenUrl, content);
if (response.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Request Token Step Failed");
}
var responseContent = await response.Content.ReadAsStringAsync();
var responseItems = responseContent.Split(new[] { '&' });
this.requestToken = responseItems[0];
this.requestTokenSecret = responseItems[1];
var url = string.Format("{0}?{1}&display=touch", AuthorizeUrl, this.requestToken);
return url;
}
public string CreateSignature(string url, string nonce, string timestamp, string callback)
{
// code removed
return signatureString;
}
private static byte[] StringToAscii(string s)
{
// code removed
return retval;
}
}
I have a console app that calls this library and it works with no problem:
public class Program
{
public static void Main(string[] args)
{
var o = new Program();
o.LinkToFitbit();
}
public void LinkToFitbit()
{
var authenticator = new Authenticator();
// this works and returns the url immediately
var url = authenticator.GetAuthUrlToken();
// code removed
}
}
When I run from my WP8 app, it just hangs when it gets to this line in the library:
var response = await httpClient.PostAsync(RequestTokenUrl, content);
Here is my WP8 code:
public partial class FitbitConnector : PhoneApplicationPage
{
public FitbitConnector()
{
InitializeComponent();
this.AuthenticateUser();
}
private void AuthenticateUser()
{
var authenticator = new Authenticator();
var url = authenticator.GetAuthUrlToken();
// code removed
}
}
This line is blocking the UI thread:
public string GetAuthUrlToken()
{
return GenerateAuthUrlToken().Result;
}
The code after the await httpClient.PostAsync() needs to be executed in the UI thread, but it can't be executed because is is blocked.
So, replace this:
private void AuthenticateUser()
{
var authenticator = new Authenticator();
var url = authenticator.GetAuthUrlToken();
// code removed
}
With this:
private async void AuthenticateUser()
{
var authenticator = new Authenticator();
var url = await authenticator.GenerateAuthUrlToken();
// code removed
}
Notice I am using async and await. You will need to make GenerateAuthUrlToken() public. You can erase GetAuthUrlToken().
In few words, Task<T>.Result is not asynchronous.
Can you post CreateSignature and StringToAscii code ? I am stuck at basic oAuth.
I can get Request token but get "Invalid OAuth Signature" while performing a request for Access Token.
Nexus, here you go. I created an OauthHelper class that I use to build the pieces I need. Have a look below. I hope this helps.
public static class OauthHelper
{
public const string ConsumerKey = "MyKey";
public const string ConsumerSecret = "MySecret";
public const string UriScheme = "https";
public const string HostName = "api.somePlace.com";
public const string RequestPath = "/services/api/json/1.3.0";
public const string OauthSignatureMethod = "HMAC-SHA1";
public const string OauthVersion = "1.0";
public static string BuildRequestUri(Dictionary<string, string> requestParameters)
{
var url = GetNormalizedUrl(UriScheme, HostName, RequestPath);
var allParameters = new List<QueryParameter>(requestParameters.Select(entry => new QueryParameter(entry.Key, entry.Value)));
var normalizedParameters = NormalizeParameters(allParameters);
var requestUri = string.Format("{0}?{1}", url, normalizedParameters);
return requestUri;
}
public static AuthenticationHeaderValue CreateAuthorizationHeader(
string oauthToken,
string oauthNonce,
string oauthTimestamp,
string oauthSignature)
{
var normalizedUrl = GetNormalizedUrl(UriScheme, HostName, RequestPath);
return CreateAuthorizationHeader(oauthToken, oauthNonce, oauthTimestamp, oauthSignature, normalizedUrl);
}
public static AuthenticationHeaderValue CreateAuthorizationHeader(
string oauthToken,
string oauthNonce,
string oauthTimestamp,
string oauthSignature,
string realm)
{
if (string.IsNullOrWhiteSpace(oauthToken))
{
oauthToken = string.Empty;
}
if (string.IsNullOrWhiteSpace(oauthTimestamp))
{
throw new ArgumentNullException("oauthTimestamp");
}
if (string.IsNullOrWhiteSpace(oauthNonce))
{
throw new ArgumentNullException("oauthNonce");
}
if (string.IsNullOrWhiteSpace(oauthSignature))
{
throw new ArgumentNullException("oauthSignature");
}
var authHeaderValue = string.Format(
"realm=\"{0}\"," +
"oauth_consumer_key=\"{1}\"," +
"oauth_token=\"{2}\"," +
"oauth_nonce=\"{3}\"," +
"oauth_timestamp=\"{4}\"," +
"oauth_signature_method=\"{5}\"," +
"oauth_version=\"{6}\"," +
"oauth_signature=\"{7}\"",
realm,
Uri.EscapeDataString(ConsumerKey),
Uri.EscapeDataString(oauthToken),
Uri.EscapeDataString(oauthNonce),
Uri.EscapeDataString(oauthTimestamp),
Uri.EscapeDataString(OauthSignatureMethod),
Uri.EscapeDataString(OauthVersion),
Uri.EscapeDataString(oauthSignature));
var authHeader = new AuthenticationHeaderValue("OAuth", authHeaderValue);
return authHeader;
}
public static string CreateSignature(
string httpMethod,
string oauthToken,
string oauthTokenSecret,
string oauthTimestamp,
string oauthNonce,
Dictionary<string, string> requestParameters)
{
// get normalized url
var normalizedUrl = GetNormalizedUrl(UriScheme, HostName, RequestPath);
return CreateSignature(
httpMethod,
oauthToken,
oauthTokenSecret,
oauthTimestamp,
oauthNonce,
requestParameters,
normalizedUrl);
}
public static string CreateSignature(
string httpMethod,
string oauthToken,
string oauthTokenSecret,
string oauthTimestamp,
string oauthNonce,
Dictionary<string, string> requestParameters,
string realm)
{
if (string.IsNullOrWhiteSpace(httpMethod))
{
throw new ArgumentNullException("httpMethod");
}
if (string.IsNullOrWhiteSpace(oauthToken))
{
oauthToken = string.Empty;
}
if (string.IsNullOrWhiteSpace(oauthTokenSecret))
{
oauthTokenSecret = string.Empty;
}
if (string.IsNullOrWhiteSpace(oauthTimestamp))
{
throw new ArgumentNullException("oauthTimestamp");
}
if (string.IsNullOrWhiteSpace(oauthNonce))
{
throw new ArgumentNullException("oauthNonce");
}
var allParameters = new List<QueryParameter>
{
new QueryParameter("oauth_consumer_key", ConsumerKey),
new QueryParameter("oauth_token", oauthToken),
new QueryParameter("oauth_nonce", oauthNonce),
new QueryParameter("oauth_timestamp", oauthTimestamp),
new QueryParameter("oauth_signature_method", OauthSignatureMethod),
new QueryParameter("oauth_version", OauthVersion)
};
allParameters.AddRange(requestParameters.Select(entry => new QueryParameter(entry.Key, entry.Value)));
// sort params
allParameters.Sort(new QueryParameterComparer());
// concat all params
var normalizedRequestParameters = NormalizeParameters(allParameters);
// create base string
var signatureBase = string.Format(
"{0}&{1}&{2}",
UrlEncode(httpMethod.ToUpperInvariant()),
UrlEncode(realm),
UrlEncode(normalizedRequestParameters));
var signatureKey = string.Format(
"{0}&{1}",
UrlEncode(ConsumerSecret),
UrlEncode(oauthTokenSecret));
// hash the base string
var hmacsha1 = new HMACSHA1(StringToAscii(signatureKey));
var signatureString = Convert.ToBase64String(hmacsha1.ComputeHash(StringToAscii(signatureBase)));
return signatureString;
}
public static string GenerateNonce()
{
var ts = new TimeSpan(DateTime.Now.Ticks);
var ms = ts.TotalMilliseconds.ToString().Replace(".", string.Empty);
var nonce = ms;
return nonce;
}
public static string GenerateTimeStamp()
{
var timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0);
var timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString(CultureInfo.InvariantCulture);
return timestamp;
}
private static string GetNormalizedUrl(string uriScheme, string hostName, string requestPath)
{
var normalizedUrl = string.Format(
"{0}://{1}{2}",
uriScheme.ToLowerInvariant(),
hostName.ToLowerInvariant(),
requestPath);
return normalizedUrl;
}
private static string NormalizeParameters(IList<QueryParameter> parameters)
{
var result = new StringBuilder();
for (var i = 0; i < parameters.Count; i++)
{
var p = parameters[i];
result.AppendFormat("{0}={1}", p.Name, p.Value);
if (i < parameters.Count - 1)
{
result.Append("&");
}
}
return result.ToString();
}
private static byte[] StringToAscii(string s)
{
var retval = new byte[s.Length];
for (var ix = 0; ix < s.Length; ++ix)
{
var ch = s[ix];
if (ch <= 0x7f)
{
retval[ix] = (byte)ch;
}
else
{
retval[ix] = (byte)'?';
}
}
return retval;
}
private static string UrlEncode(string value)
{
const string Unreserved = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
var result = new StringBuilder();
foreach (char symbol in value)
{
if (Unreserved.IndexOf(symbol) != -1)
{
result.Append(symbol);
}
else
{
result.Append('%' + string.Format("{0:X2}", (int)symbol));
}
}
return result.ToString();
}
}
public class QueryParameter
{
public QueryParameter(string name, string value)
{
this.Name = name;
this.Value = value;
}
public string Name { get; private set; }
public string Value { get; private set; }
}
public class QueryParameterComparer : IComparer<QueryParameter>
{
public int Compare(QueryParameter x, QueryParameter y)
{
return x.Name == y.Name
? string.Compare(x.Value, y.Value)
: string.Compare(x.Name, y.Name);
}
}
Since you are using .Result or .Wait or await this will end up causing a deadlock in your code.
you can use ConfigureAwait(false) in async methods for preventing deadlock
like this:
var response = await httpClient.PostAsync(RequestTokenUrl, content).ConfigureAwait(false);
you can use ConfigureAwait(false) wherever possible for Don't Block Async Code .

Categories

Resources