System.Data.SqlClient.SqlException: Invalid column name 'Email' - asp.net-mvc-4

I'm working on a new ASP.Net MVC 4 app and testing user login. I am getting following exception:
System.Data.SqlClient.SqlException: Invalid column name 'Email'
I'm using the example from http://kevin-junghans.blogspot.com/2013/02/adding-email-confirmation-to.html.
Here's the appropriate code:
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
string confirmationToken =
WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { Email = model.Email }, true);
System.Net.Mail.MailAddress from = new System.Net.Mail.MailAddress("noreply#cardmage.com");
System.Net.Mail.MailAddress[] to = new System.Net.Mail.MailAddress[1];
to[1] = new System.Net.Mail.MailAddress(model.Email);
System.Net.Mail.MailAddress[] cc = new System.Net.Mail.MailAddress[0];
System.Net.Mail.MailAddress[] bcc = new System.Net.Mail.MailAddress[0];
String Subject = "Please verify your e-mail address.";
String body = String.Format("Thank you for registering with CardMage." +
"To verify your account, please follow this link." +
"http://www.cardmage.co/Account/RegisterConfirmation/{0}", confirmationToken);
System.Net.NetworkCredential nc = new NetworkCredential("foo", "bar");
SendGrid sg = SendGrid.GetInstance(from, to, cc, bcc, Subject, body, "");
SMTP s = SMTP.GetInstance(nc);
s.Deliver(sg);
return RedirectToAction("RegisterStepTwo", "Account");
What am I doing wrong? I tried to find the solution from from the google search but no luck. I found this SO question that has the property values formatted the same way I do, so I checked my database, but the Email column does not exist. Can someone please point me in the right direction? Thank you for your time and consideration.

To get your email field updated by the call to CreateUserAndAccount, do the following:
1 Ensure the database table you are using has an email column.
2 Change the Account model UserProfile to include your email field.
3 Change the Register view to include your email.
4 Change the AccountController to include an anomymous object (this you have done)
Then, when you Register a new user, their email will be stored in the database table.
This works for me.

Related

login using custom/added field to the user profile in liferay 7.4

I am trying to add new field to the user profile (student number) and allow users to login using either email or the new field (student number) with the same password for both.
I have overridden login.jsp to allow both Email and Student Number.
My idea is to override the login action command with something similar to the code below:
#Component(
property = {
"javax.portlet.name=com_liferay_login_web_portlet_LoginPortlet",
"mvc.command.name=/login/login"
},
service = MVCActionCommand.class
)
public class CustomLoginActionCommand extends BaseMVCActionCommand {
#Override
protected void doProcessAction(ActionRequest actionRequest,
ActionResponse actionResponse) throws Exception {
ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
WebKeys.THEME_DISPLAY);
HttpServletRequest request = PortalUtil.getOriginalServletRequest(
PortalUtil.getHttpServletRequest(actionRequest));
HttpServletResponse response = PortalUtil.getHttpServletResponse(
actionResponse);
String login = ParamUtil.getString(actionRequest, "login");
String password = actionRequest.getParameter("password");
boolean rememberMe = ParamUtil.getBoolean(actionRequest, "rememberMe");
String authType = CompanyConstants.AUTH_TYPE_EA;
String email = "";
if(isValidEmail(login)){ //if the user trying to login with his email
email = login ;
}
else if(isNumeric(login)){ //check if the user trying to login with his student number
//fetch User by Student Number (login)
//e.g. fetchUserByStudentNumber(login)
//get the Email Adress for the retrieved user object and use it to login
email = user.getEmailAddress();
}
else{
// Exception
}
AuthenticatedSessionManagerUtil.login(request, response, email, password, rememberMe, authType);
actionResponse.sendRedirect(themeDisplay.getPathMain());
}
}
is this the right way to achive similar requierment?
in Liferay 7.4 U46+, we can extend supported system services with Liferay Objects. so I have two options to extend the User Profile, 1- by adding a new field to the User object. or 2- by creating a new "custom field". which option is better?
in both options, how to force unique values in the added field (student number)?
how to retrieve user object by using added field (fetchUserByStudentNumber)?
Appreciate your feedback!
Thanks
Overwriting the portal login command is possible, but I would rather use a custom Authenticator to not overwrite other logic implemented in the MVC action component. As you want booth (mail and student number), you could implement authenticateByEmailAddress like in Password-Based-Authentication-Pipelines and check both authentication results with a boolean OR approach.
Extending portal model objects should rather be implemented via Custom Fields. Fetching a user like in fetchUserByStudentNumber you will probably need the ExpandoValue service and a dynamic query. Maybe there are better approached, but this is what comes into my mind first.

How to send email from any one email using Microsoft Graph

I am using microsoft graph to send email. This email I want to send from any email that exists in the Active directory.
I already have get the permission on Mail.Send and have admin consent on Azure.So all set on the Azure level for access and permission.
Now when come to code. I have searched for but I am not able to figure out how to call the Microsoft graph api to send the email. Below is the code that I have been finding when I am doing search. How I can replace the below code to send the email to anyone from anyone in Azure AD to anyone in Azure AD. Also the code for send email 'Send AS'.
await graphClient.Me.Messages
.Request()
.AddAsync(message);
The intention is the signed in user will not send email from his email
address, the email notification will be asthmatically sent by someone
else name to someone.
Then I think you wanna provide a sending email to your users, users can choose who received the email, but all the email should be sent be a specific account, such as admin#xxx.onmicrosoft.com, then you should know something about the sending email api.
As #user2250152 mentioned, await graphClient.Users["userId"], here the userId means who send the email, as your requirement is sending all emails from one specific email address, it should hardcode as admin#xxx.onmicrosoft.com.
The next is how to send the email, calling ms graph api should offer an access token, as your requirement is sending email by the application but not every user, so I'm afraid the client credential flow is a better choice so that when the scenario comes to sending email from several specific email addresses, you don't need to change the flow then. Now you need to require your tenant admin to add Mail.Send Application api permission in azure ad to use this kind of flow.
And here's the code:
using Azure.Identity;
using Microsoft.Graph;
var mesg = new Message
{
Subject = "Meet for lunch?",
Body = new ItemBody
{
ContentType = BodyType.Text,
Content = "The new cafeteria is open."
},
ToRecipients = new List<Recipient>
{
new Recipient
{
EmailAddress = new EmailAddress
{
//who will receive the email
Address = "xxx#gmail.com"
}
}
},
Attachments = new MessageAttachmentsCollectionPage()
};
var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "your_tenant_name.onmicrosoft.com";
var clientId = "azure_ad_app_client_id";
var clientSecret = "client_secret_for_the_azuread_app";
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
await graphClient.Users["user_id_which_you_wanna_used_for_sending_email"].SendMail(mesg, false).Request().PostAsync();
You can send mail from other user this way.
var message = new Message
{
Subject = "Subject",
Body = new ItemBody
{
ContentType = BodyType.Text,
Content = "Content"
},
ToRecipients = new List<Recipient>()
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = "john.doe#contoso.onmicrosoft.com"
}
}
}
};
var saveToSentItems = false;
await graphClient.Users["userId"]
.SendMail(message,saveToSentItems)
.Request()
.PostAsync();
userId is the unique identifier for the user. Instead of userId you can use userPrincipalName. The UPN is an Internet-style login name for the user based on the Internet standard RFC 822. By convention, this should map to the user's email name.
Resources:
Send mail
User resource

Unable to login with users created via dbContext in asp.net core mvc

I am trying to seed the db with initial data and I am using the following code to create the users. Users get created, passwords hashed, etc but when I try to login with my password, it fails to log me in with error message: Invalid login attempt. What am I doing wrong? I am using asp.net core mvc application with identity template, not a custom login.
var mymail = "my#my.com";
var mypw = "Test1.";
var applicationUsers = new ApplicationUser[]
{
new ApplicationUser {
UserName = Constants.AnonUserName,
Email = "Anonymous#xyz.com"
},
new ApplicationUser {
UserName = mymail,
Email = mymail
}
};
var pwHasher = new PasswordHasher<ApplicationUser>();
applicationUsers.ToList().ForEach(u =>
{
u.PasswordHash = pwHasher.HashPassword(u, mypw);
context.ApplicationUsers.Add(u);
});
context.SaveChanges();
Login fails because NormalizedUserName field in db is null and during login, following query is issued (which fails):
SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName"
FROM "AspNetUsers" AS "u"
WHERE "u"."NormalizedUserName" = $1
LIMIT 1
DETAIL: parameters: $1 = 'MY#MY.COM'
I guess the solution is to inject ILookupNormalizer service and normalize with its Normalize method but it is already too much work. I am injecting UserManager service and using its CreateAsync method to create a user with a password as advised by #Tseng above in comments.

ASP.Net Core (MVC6) Unable to login with seeded users

This is how I did it.
public class SeedData
{
public static void Initialize(IServiceProvider serviceProvider)
{
var context = serviceProvider.GetService<ApplicationDbContext>();
var userManager = serviceProvider.GetService<UserManager<ApplicationUser>>();
var user0 = new ApplicationUser { UserName = "bob", Email = "bob#asd.com" };
var result = userManager.CreateAsync(user0, "Password1!").Result;
}
}
The initialize method is run in Startup.cs in the Configure method at the very end:
SeedData.Initialize(app.ApplicationServices);
When I look at the database, the users are there as expected. When I try to login though, I get an invalid login attempt. When I try to Register the user with the same email address, it doesn't detect a duplicate entry and adds a new user with the same address.
UserManager seems to behave differently in the context of a Controller. How would I be able to create seed users properly so I can login with them?
Id AccessFailedCount ConcurrencyStamp Email EmailConfirmed LockoutEnabled LockoutEnd NormalizedEmail NormalizedUserName PasswordHash PhoneNumber PhoneNumberConfirmed SecurityStamp TwoFactorEnabled UserName
e3ff23eb-5db9-4eb3-871e-e95232178e1c 0 241c36e0-b0a9-4c86-af98-6d38132947e9 bob#asd.com 0 1 NULL BOB#ASD.COM BOB AQAAAAEAACcQAAAAECFF4uxt8kT3nZgU9nhfticduyI3OXAxCZg+XJT/0Id280Tgf6B9cCY+Il6beRTFWw== NULL 0 3e9a2185-d248-4589-aa30-ecbb145787ff 0 bob
I have just encountered with this problem.
as the following code
var userManager = serviceProvider.GetService>();
ApplicationUser user0, user1;
if (context.Users.Any(u => u.UserName == "nemo#mail.com"))
user0 = context.Users.First(u => u.UserName == "nemo#mail.com");
else
{
user0 = new ApplicationUser { UserName = "nemo#mail.com", Email = "nemo#mail.com" };
var result = userManager.CreateAsync(user0, "Abc123").Result;
}
if (context.Users.Any(u => u.UserName == "teresa#mail.com"))
user1 = context.Users.First(u => u.UserName == "teresa#mail.com");
else
{
user1 = new ApplicationUser { UserName = "teresa#mail.com", Email = "teresa#mail.com" };
var result = userManager.CreateAsync(user1, "Abc123").Result;
}
When I login with "teresa#mail.com" the login will reject by message "Invalid login attempt.".
But with the "nemo#mail.com" the login will success.
As the result, ASP.net seems to use UserName & password for login verification.
I can see that "email address as username" has been mentioned in comments but I'm posting this answer for anyone experiencing the same symptoms. I found that when seeding the database with a user that had a different username and email address, I could not log in as that user. Registering a new user on the site worked fine and I could login as a user that I'd registered. Looking in the database at the seeded user and the registered user I saw that the difference was that the registered user has its email address as its username.
So yes, an application built on the Visual Studio template has an assumption that you want to us email addresses as usernames. Look at the AccountController class -> Login Action Method (POST). It calls SignInManager.PasswordSignInAsync() with the first argument as model.Email. Hover your mouse over that method or right-click go to definition and you'll see that the first argument is expected to be string userName.
So you have two options:
Modify the controller, view and viewmodel involved with logon to allow user to enter a username at logon.
Use email address as username when seeding users into the database.

Searching user by id by exact match in LDAP (SharePoint 2010 people picker)

I am trying to search a user in the LDAP and resolve his name in SharePoint PeoplePicker
User types user's idsid in the PeoplePicker and then hit CheckName
The code calls SearchSingleUser() with the typed userid.
Example: I type 'xyz' and hit CheckName
The method below would then search LDAP for users with SamAccountName='xyz' for exact match. If match found then it should resolve the idsid in peoplepicker
If the LDAP has Domain\xyz but user types xyz, it won't match and won't resolve
But what I am seeing is that the name gets half resolved.
Any clue what I am missing as far as searching for exact match of a property?
This is my code:
public static string _LDAPSearchDefSingleUser = "(&(objectClass=user)(SamAccountName={0}))";
public static SearchResultCollection SearchSingleUser(string searchPattern)
{
using (DirectoryEntry root = new DirectoryEntry(ldapPath, username, password))
{
root.AuthenticationType = AuthenticationTypes.None;
string filter = string.Format(_LDAPSearchDefSingleUser, searchPattern);
using (DirectorySearcher searcher = new DirectorySearcher(root))
{
searcher.ReferralChasing = ReferralChasingOption.All;
searcher.SearchScope = SearchScope.Subtree;
searcher.Filter = filter;
searcher.PropertiesToLoad.Add("objectclass");
searcher.PropertiesToLoad.Add("SamAccountName");
SearchResultCollection results = searcher.FindAll();
return results;
}
}
}
Not sure to understantd your question, but I confirm that the following filter :
(&(objectClass=user)(SamAccountName=xyz))
in an LDAP search returns only THE object of class user with the attribute SamAccountName exactly equal to 'xyz'.
In your case, if you've got multiple match, it's because you enter '*xyz' or '*xyz*'.
For your information I use quite the same code and it works so.