Asp.net Identity UserManager error:UserName is null - asp.net-identity-2

UserManager CreateAsyncy gives error: UserName cannot be empty or null.
Below is my code snippet:
var contractor = new Contractor()
{
UserName = contractorModel.UserName,
Email = contractorModel.Email,
EmailConfirmed = true,
SecurityStamp = Guid.NewGuid().ToString()
};
var result = await UserManager.CreateAsync(contractor,"Passw0rd!");

I fixed it by UserName = contractorModel.Email;

Related

How to retrieve Claims Value in .Net Core 2.0

As it says in the title I have already assigned claims to the registered user, I am now trying to retrieve the claim value when the user logs into the application within the UserClaims table in sql server which I find a bit difficult to do as this is my first time using claims.
Looking for directions on our to achieve this, thank you in advance.
public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.UserName, Email = model.Email, UserRoleId = model.RoleId };
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme);
await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl);
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation("User created a new account with password.");
await addUserClaims(model.CusomterId, model.UserName);
return RedirectToLocal(returnUrl);
}
AddErrors(result);
}
List<UserRole> roles = _userRoleRepo.GetAll();
model.CreateRoleList(roles);
List<Customer> customers = await _customerRepository.GetAll();
model.SetupCustomerOptionList(customers);
// If we got this far, something failed, redisplay form
return View(model);
}
private async Task addUserClaims(string CustomerID ,string username)
{
// Customer customer = _customerRepository.GetById(customerid);
List<Customer> customers = await _customerRepository.GetAll();
Customer customer = _customerRepository.GetById(CustomerID);
var user = await _userManager.FindByNameAsync(username);
;
await _userManager.AddClaimAsync(user, new Claim(ClaimTypes.Name, CustomerID));
}
Set
var claims = new List<Claim>
{
new Claim("Currency", "PKR")
};
Get
#User.Claims.FirstOrDefault(c => c.Type == "Currency").Value
Very easy
public static class IdentityExtension
{
public static string GetId(this IIdentity identity)
{
ClaimsIdentity claimsIdentity = identity as ClaimsIdentity;
Claim claim = claimsIdentity.FindFirst(ClaimTypes.NameIdentifier);
return claim.Value;
}
}
Example
User.Identity.GetId();

Active Directory authentication for Umbraco 7.6 gets stuck in a re-direct loop

I am currently using an Umbraco library to extend the Authentication possibilities and enable back office authentication with Active Directory.
https://github.com/umbraco/UmbracoIdentityExtensions
After installing the library and following the blog post below, I was able to display an external login button, authenticate with Active Directory and add a user and external login to the Umbraco database.
https://www.jdibble.co.uk/blog/securing-umbraco-backoffice-with-azure-active-directory/
This then sends you back to the /umbraco login page in a continuous loop. As described by this blog post https://our.umbraco.org/forum/developers/extending-umbraco/75256-login-uisng-azure-ad-redirects-allways-to-login-page
Has anyone faced this issue and solved it? Or have any useful suggestions?
The code being used...
public static void ConfigureBackOfficeAzureActiveDirectoryAuth(this IAppBuilder app,
string tenant, string clientId, string postLoginRedirectUri, Guid issuerId,
string caption = "Active Directory", string style = "btn-microsoft", string icon = "fa-windows")
{
var authority = string.Format(
CultureInfo.InvariantCulture,
"https://login.microsoftonline.com/{0}",
tenant);
var adOptions = new OpenIdConnectAuthenticationOptions
{
SignInAsAuthenticationType = Constants.Security.BackOfficeExternalAuthenticationType,
ClientId = clientId,
Authority = authority,
RedirectUri = postLoginRedirectUri,
AuthenticationMode = AuthenticationMode.Passive,
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthorizationCodeReceived = async context =>
{
if (System.Diagnostics.Debugger.IsAttached)
System.Diagnostics.Debugger.Break();
var userService = ApplicationContext.Current.Services.UserService;
var stuff = (List<Claim>)context.JwtSecurityToken.Claims;
var email = stuff.FirstOrDefault(x => x.Type == "unique_name").Value;
var issuer = stuff.FirstOrDefault(x => x.Type == "iss").Value;
var providerKey = stuff.FirstOrDefault(x => x.Type == "sub").Value;
var name = stuff.FirstOrDefault(x => x.Type == "name").Value;
var userManager = context.OwinContext.GetUserManager<BackOfficeUserManager>();
var user = userService.GetByEmail(email);
if (user == null)
{
var writerUserType = userService.GetUserTypeByName("writer");
user = userService.CreateUserWithIdentity(email, email, writerUserType);
}
var identity = await userManager.FindByEmailAsync(email);
if (identity.Logins.All(x => x.ProviderKey != providerKey))
{
identity.Logins.Add(new IdentityUserLogin(issuer, providerKey, user.Id));
identity.Name = name;
var result = userManager.Update(identity);
}
},
}
};
adOptions.ForUmbracoBackOffice(style, icon);
adOptions.Caption = caption;
//Need to set the auth type as the issuer path
adOptions.AuthenticationType = string.Format(
CultureInfo.InvariantCulture,
"https://sts.windows.net/{0}/",
issuerId);
adOptions.SetExternalSignInAutoLinkOptions(new ExternalSignInAutoLinkOptions(autoLinkExternalAccount: true));
app.UseOpenIdConnectAuthentication(adOptions);
}

Standard for creating JWT in C#

I am struggling to figure out a way to standardize JWT creation across a product.
Following are the two implementations that i have come across
Uses JwtSecurityToken where audience can be null and in this implementation, we have used a clientspecific GUID as a audienceID
string audienceId = data.Properties.Dictionary.ContainsKey(AudiencePropertyKey) ? data.Properties.Dictionary[AudiencePropertyKey] : null;
if (string.IsNullOrWhiteSpace(audienceId)) throw new InvalidOperationException("AuthenticationTicket.Properties does not include audience");
ClientDataModel audience = ClientStore.FindAudience(audienceId);
string symmetricKeyAsBase64 = audience.Base64Secret;
var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64);
var signingKey = new HmacSigningCredentials(keyByteArray);
var issued = data.Properties.IssuedUtc;
var expires = data.Properties.ExpiresUtc;
//Generate Token based on the Passed information as Parameters
var token = new JwtSecurityToken(_issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingKey);
var handler = new JwtSecurityTokenHandler();
//Write Token in the JWT Format
var jwt = handler.WriteToken(token);
return jwt;
Using SecurityTokenDescriptor where AppliesToAddress is a must and throws an error in case it is not provided. As per oauth specification, audience is a optional parameter
var tokenHandler = new JwtSecurityTokenHandler();
var now = DateTime.UtcNow;
string symmetricKeyAsBase64 = ConfigurationManager.AppSettings["AudienceSecret"];
var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64);
var signingKey = new HmacSigningCredentials(keyByteArray);
// Token Creation
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, ""),
}),
TokenIssuerName = ConfigurationManager.AppSettings["Issuer"],
AppliesToAddress = ConfigurationManager.AppSettings["AppliesToAddress"],
Lifetime = new Lifetime(now, now.AddMinutes(Int32.Parse((string)ConfigurationManager.AppSettings["TokenValidFor"]))),
SigningCredentials = signingKey
};
JwtSecurityToken token = tokenHandler.CreateToken(tokenDescriptor) as JwtSecurityToken;
return token.RawData;
Can someone suggest which one to use?

CoSign API: SPML WS - User Management Query

I'm trying to create a new user using the CoSign SPML WS.
The code I'm using (C#.NET) is below. Can someone please let me know if the PSOIdentifierType.ID is correct (i.e. "The ID of the User") and what should the Target ID be, I think it should be blank as the user does not exist yet.
private const readonly string addTargetDB = "CoSignDB";
public void CreateBasicUser(string userName, string userLoginName, string userPassword, string userCN, string userEmail)
{
SPMLSoapClient client = new SPMLSoapClient();
AddRequestType request = new AddRequestType();
PSOIdentifierType psoCreationType = new PSOIdentifierType();
psoCreationType.ID = userName;
psoCreationType.targetID = ""; //The parameter that was returned in the ListTargets operation
UserRecord newUserRecord = new UserRecord();
newUserRecord.UserLoginName = userLoginName;
newUserRecord.Password = userPassword;
newUserRecord.UserCN = userCN;
newUserRecord.EmailAddress = userEmail;
newUserRecord.RightsMask = (uint)1; // 1 - User
newUserRecord.UserKind = UserKindEnum.User;
request.returnData = ReturnDataType.everything;
request.targetID = addTargetDB;
request.psoID = psoCreationType;
request.UserRecord = newUserRecord;
AddResponseType clientAddResponse = client.add(request);
if(clientAddResponse.status == StatusCodeType.success)
{
// OK
}
else if(clientAddResponse.status == StatusCodeType.failure)
{
// Fail
}
}
The id of the user is correct (it should be the username) and the TargetID should be "CoSignDB"

Orchard CMS Duplicate entry when creating a user

I have been breaking my head over this. Please take a look at this code. This code is in the customer controller.
[HttpPost]
[Themed]
public ActionResult Register(string email, string password, string confirmPassword, Gender gender, string givenName, string familyName, string insertion, DateTime birthDate) {
ViewData["PasswordLength"] = MinPasswordLength;
var shape = _orchardServices.New.Register();
//1. Initialize new content of customer contenttype
var customer = _orchardServices.ContentManager.New("Customer");
if (customer != null) {
//2. Define the parts that need to be filled
var userPart = customer.As<UserPart>();
var customerPart = customer.As<CustomerPart>();
//3. Let's validate first if the user can be created
if (userPart!=null) {
//shape.Customer = _orchardServices.ContentManager.UpdateEditor(customer, this);
if (!ModelState.IsValid)
{
_orchardServices.TransactionManager.Cancel();
return new ShapeResult(this, shape);
}
//4. Now validate the user credentials.
if (ValidateRegistration(email, password, confirmPassword)) {
//Now create the actual customer.
userPart.UserName = email;
userPart.Email = email;
userPart.NormalizedUserName = email.ToLowerInvariant();
userPart.Record.HashAlgorithm = "SHA1";
userPart.Record.RegistrationStatus = UserStatus.Approved;
userPart.Record.EmailStatus = UserStatus.Approved;
customerPart.CreatedAt = DateTime.UtcNow;
customerPart.LastLogonAt = DateTime.UtcNow;
_membershipService.SetPassword(userPart, password);
var user = customerPart.User;
_authenticationService.SignIn(user, false /* createPersistentCookie */);
return Redirect("~/");
}
}
}
When this code is run, I end up with two entries for UserPart in my database. One with a related CustomerPart and one not.

Resources