Related
Trying to port ASP.NET MVC4 HTML offline application to .NET 5.
It should allow to enter order without internet connenction and send it to MVC 5 controller over internet if connection is present.
It has manifest controller
namespace Store.Controllers
{
public class MobileOrderController : ControllerBase
{
public async Task<IActionResult> Manifest()
{
return new AppCacheResult(new[] {
BundleTable.Bundles.ResolveBundleUrl("~/bundles/jquery")
},
fingerprint: BundleTable.Bundles
.FingerprintsOf("~/bundles/jquery"));
}
}
}
public class AppCacheResult : IActionResult
{
public AppCacheResult(
IEnumerable<string> cacheAssets,
IEnumerable<string> networkAssets = null,
IDictionary<string, string> fallbackAssets = null,
string fingerprint = null)
{
if (cacheAssets == null)
{
throw new ArgumentNullException("cacheAssets");
}
CacheAssets = cacheAssets.ToList();
if (!CacheAssets.Any())
{
throw new ArgumentException(
"Cached url cannot be empty.", "cacheAssets");
}
NetworkAssets = networkAssets ?? new List<string>();
FallbackAssets = fallbackAssets ?? new Dictionary<string, string>();
Fingerprint = fingerprint;
}
protected IEnumerable<string> CacheAssets { get; private set; }
protected IEnumerable<string> NetworkAssets { get; private set; }
protected IDictionary<string, string> FallbackAssets
{
get;
private set;
}
protected string Fingerprint { get; private set; }
public async Task ExecuteResultAsync(ActionContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
var response = context.HttpContext.Response;
response.Cache.SetMaxAge(TimeSpan.Zero);
response.ContentType = "text/cache-manifest";
response.ContentEncoding = Encoding.UTF8; // needs to be utf-8
response.Write(GenerateContent());
}
protected virtual string GenerateHeader()
{
return "CACHE MANIFEST" + Environment.NewLine;
}
protected virtual string GenerateFingerprint()
{
return string.IsNullOrWhiteSpace(Fingerprint) ?
string.Empty :
Environment.NewLine +
"# " + Fingerprint +
Environment.NewLine;
}
protected virtual string GenerateCache()
{
var result = new StringBuilder();
result.AppendLine();
result.AppendLine("CACHE:");
CacheAssets.ToList().ForEach(a => result.AppendLine(a));
return result.ToString();
}
protected virtual string GenerateNetwork()
{
var result = new StringBuilder();
result.AppendLine();
result.AppendLine("NETWORK:");
var networkAssets = NetworkAssets.ToList();
if (networkAssets.Any())
{
networkAssets.ForEach(a => result.AppendLine(a));
}
else
{
result.AppendLine("*");
}
return result.ToString();
}
protected virtual string GenerateFallback()
{
if (!FallbackAssets.Any())
{
return string.Empty;
}
var result = new StringBuilder();
result.AppendLine();
result.AppendLine("FALLBACK:");
foreach (var pair in FallbackAssets)
{
result.AppendLine(pair.Key + " " + pair.Value);
}
return result.ToString();
}
private string GenerateContent()
{
var content = new StringBuilder();
content.Append(GenerateHeader());
content.Append(GenerateFingerprint());
content.Append(GenerateCache());
content.Append(GenerateNetwork());
content.Append(GenerateFallback());
var result = content.ToString();
return result;
}
}
This causes compile error in .NET 5 since response.Cache and response.ContentEncoding does not exis in lines
response.Cache.SetMaxAge(TimeSpan.Zero);
response.ContentEncoding = Encoding.UTF8;
also response.Write does not exist in line
response.Write(GenerateContent());
and BundleTable.Bundles does not exist in .NET 5
How to convert it to .NET 5 ?
Or is there better way to create HTML offline application in .NET 5 using ASP.NET MVC Core.
Cache settings you could handle in startup.cs ConfigureServices method:
services.AddMvc(options =>
{
options.CacheProfiles.Add("Default30",
new CacheProfile()
{
Duration = 30
});
});
For the encoding you could use following snippet:
var mediaType = new MediaTypeHeaderValue("application/json");
mediaType.Encoding = Encoding.UTF8;
httpContext.Response.ContentType = mediaType.ToString();
responce.Write could be replaced with this:
byte[] bytes = Encoding.ASCII.GetBytes(GenerateContent());
await HttpContext.Response.Body.WriteAsync(bytes);
I'm attempting to setup a custom policy provider in asp.net core. I need to pass in several custom authorization attributes to the provider but struggling with how to do so.
I have it setup to accept one enum array currently and is working fine. However, I would like to add 2 more enum arrays as additional, optional parameters to the authorization attribute.
Attribute as it is now:
[LEMClaimAuthorize(new ELocation[] { ELocation.Indy, ELocation.Columbus })]
Would like for it to work like so:
[LEMClaimAuthorize(new ELocation[] { ELocation.Indy, ELocation.Columbus },
new EEntity[] { EEntity.JobTool })]
LEMClaimAuthorizeAttribute is:
public class LEMClaimAuthorizeAttribute : AuthorizeAttribute
{
const string POLICY_PREFIX = "LEMClaim";
public ELocation[] Locations
{
get
{
if (Enum.TryParse(typeof(ELocation[]), Policy.Substring(POLICY_PREFIX.Length), out var locations) )
{
return (ELocation[]) locations;
}
return default(ELocation[]);
}
set
{
int[] intVals = Array.ConvertAll(value, val => (int)val);
string arrayVal = string.Join(",", intVals);
Policy = $"{POLICY_PREFIX}{arrayVal}";
}
}
//remaining code omitted for brevity
}
Custom Authorization Policy Provider:
public class LEMClaimPolicyProvider : IAuthorizationPolicyProvider
{
const string POLICY_PREFIX = "LEMClaim";
public DefaultAuthorizationPolicyProvider FallbackPolicyProvider { get; }
public LEMClaimPolicyProvider(IOptions<AuthorizationOptions> options)
{
FallbackPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
}
public Task<AuthorizationPolicy> GetDefaultPolicyAsync() => FallbackPolicyProvider.GetDefaultPolicyAsync();
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
if (!policyName.StartsWith(POLICY_PREFIX, StringComparison.OrdinalIgnoreCase))
return FallbackPolicyProvider.GetPolicyAsync(policyName);
string val = policyName.Substring(POLICY_PREFIX.Length);
//CONVERT STRING TO INT[]
int[] ia = val.Split(',').Select(n => Convert.ToInt32(n)).ToArray();
ELocation[] locations = (ELocation[])(object)ia;
var policy = new AuthorizationPolicyBuilder();
policy.AddRequirements(new LEMClaimRequirement(locations));
return Task.FromResult(policy.Build());
}
}
This IS working for one enum array only.
How do I get it to work with other enum array parameters?
If there is a better way, in general, I'm all ears
Thank you for your help!
For Custom Policy Provider, it uses LEMClaimAuthorizeAttribute to build the Policy, and then check the generated policys. For passing multiple parameters to LEMClaimAuthorizeAttribute, you need to pay attention to the process to generate the policy string and extract policys from the policystring.
For a solution, follow steps below:
LEMClaimAuthorizeAttribute.cs
public class LEMClaimAuthorizeAttribute : AuthorizeAttribute
{
public LEMClaimAuthorizeAttribute(ELocation[] eLocations, EEntity[] eEntities = null)
//public LEMClaimAuthorizeAttribute(ELocation[] eLocations)
{
Locations = eLocations;
Entitys = eEntities;
}
const string POLICY_PREFIX_ELocation = "LEMClaim.ELocation";
const string POLICY_PREFIX_EEntity = "LEMClaim.EEntity";
public ELocation[] Locations
{
get
{
if (Enum.TryParse(typeof(ELocation[]), Policy.Substring(POLICY_PREFIX_ELocation.Length), out var locations))
{
return (ELocation[])locations;
}
return default(ELocation[]);
}
set
{
if (value != null)
{
int[] intVals = Array.ConvertAll(value, val => (int)val);
string arrayVal = string.Join(",", intVals);
Policy = Policy == null ? $"{POLICY_PREFIX_ELocation}{arrayVal}" : Policy + $";{POLICY_PREFIX_ELocation}{arrayVal}";
}
}
}
public EEntity[] Entitys
{
get
{
if (Enum.TryParse(typeof(EEntity[]), Policy.Substring(POLICY_PREFIX_EEntity.Length), out var locations))
{
return (EEntity[])locations;
}
return default(EEntity[]);
}
set
{
if (value != null)
{
int[] intVals = Array.ConvertAll(value, val => (int)val);
string arrayVal = string.Join(",", intVals);
Policy = Policy == null ? $"{POLICY_PREFIX_EEntity}{arrayVal}" : Policy + $";{POLICY_PREFIX_EEntity}{arrayVal}";
}
}
}
//remaining code omitted for brevity
}
LEMClaimRequirement.cs
public class LEMClaimRequirement : IAuthorizationRequirement
{
public LEMClaimRequirement(ELocation[] eLocations, EEntity[] eEntities = null)
{
Locations = eLocations;
Entitys = eEntities;
}
public ELocation[] Locations
{
get; set;
}
public EEntity[] Entitys
{
get; set;
}
}
LEMClaimPolicyProvider.cs
public class LEMClaimPolicyProvider : IAuthorizationPolicyProvider
{
const string POLICY_PREFIX = "LEMClaim";
const string POLICY_PREFIX_ELocation = "LEMClaim.ELocation";
const string POLICY_PREFIX_EEntity = "LEMClaim.EEntity";
public DefaultAuthorizationPolicyProvider FallbackPolicyProvider { get; }
public LEMClaimPolicyProvider(IOptions<AuthorizationOptions> options)
{
FallbackPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
}
public Task<AuthorizationPolicy> GetDefaultPolicyAsync() => FallbackPolicyProvider.GetDefaultPolicyAsync();
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
if (!policyName.StartsWith(POLICY_PREFIX, StringComparison.OrdinalIgnoreCase))
return FallbackPolicyProvider.GetPolicyAsync(policyName);
var val = policyName.Split(";");
//get locations
int[] ia1 = val.FirstOrDefault(k => k.StartsWith(POLICY_PREFIX_ELocation, StringComparison.OrdinalIgnoreCase))
.Substring(POLICY_PREFIX_ELocation.Length)
.Split(',').Select(n => Convert.ToInt32(n)).ToArray();
ELocation[] locations = (ELocation[])(object)ia1;
int[] ia2 = val.FirstOrDefault(k => k.StartsWith(POLICY_PREFIX_EEntity, StringComparison.OrdinalIgnoreCase))
?.Substring(POLICY_PREFIX_EEntity.Length)
?.Split(',').Select(n => Convert.ToInt32(n)).ToArray();
EEntity[] entitys = (EEntity[])(object)ia2;
var policy = new AuthorizationPolicyBuilder();
policy.AddRequirements(new LEMClaimRequirement(locations, entitys));
return Task.FromResult(policy.Build());
}
}
Use
[LEMClaimAuthorize(new ELocation[] { ELocation.Indy, ELocation.Columbus })]
public ActionResult One()
{
return View();
}
[LEMClaimAuthorize(new ELocation[] { ELocation.Indy, ELocation.Columbus }, new EEntity[] { EEntity.JobTool })]
public ActionResult Two()
{
return View();
}
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);
}
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.
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 .