0

In ASP.NET MVC, you get the default AspNetUsers table that stores all user data.

Now in most projects, you want to refer to the user that created, for example, a post. You also want to keep your database logic separate from your web logic, so you most likely put database logic in a class library.

But then, you encounter some issues: How do I refer to a AspNetUser? Should I move the ApplicationUser to the class Library? Should I even add foreign keys to this table?

I've seen many questions and answers about how to add a foreign key to AspNetUser table and how to move the ApplicationUser part to the Class Library, but I have my doubts in terms of security for the following things:

  • Part of the database is going to be exposed through an API, mostly for AngularJS Client-Side calls, but later perhaps for third-party websites. Having a foreign key to the UserId in the a table will expose the UserId on a GET call, which I've been told that this should be kept secure... right?
  • Isn't the default security logic template created in such a way that modifying it should be avoided? (Moving ApplicationUser to class Library).
  • To get the logged in user you have to use System.Web.HttpContext.Current.User.Identity.GetUserId();, which I'm not sure about how secure this is in a class library and if this is any good as it uses System.Web, is it common to use this in a class library that should only handle database logic?
  • It still requires an correct connection string in web.config, so the database handling still isn't really separated from the MVC application.
  • Calling the database correctly for userId should be avoided according to this answer.

So let's just say this is not a good way of creating your project, what are my alternatives? How would I correctly refer to an user?

In another project I used a third table, which contains additional information about the user, where one string is the e-mail address. This e-mail address is sequel (and unique) to the logged in Username (User.Identity.Name). This third table is only exposed through the API in such a way that it hides the e-mail address. It still requires System.Web.HttpContext.Current.User.Identity.Name; though.

My question to you guys is, What is best practice in 2015?

Community
  • 1
  • 1
CularBytes
  • 9,924
  • 8
  • 76
  • 101

1 Answers1

2

Well, that is an interesting question. The following answers are based in my opinion.

How do I refer to a AspNetUser? Should I move the ApplicationUser to the class Library?

In that case, you should have the ApplicationUser class as part of the Class Library Project (usually called Infrastructure). Once you are using EF, you must have all the classes to control its relationships.

Answering the question: Yes, you should!

Should I even add foreign keys to this table?

Yes, you should! That's why the class is there, to be modified as you need. Typically, the other classes has FKs that references the ASP.NET user.

Part of the database is going to be exposed through an API, mostly for AngularJS Client-Side calls, but later perhaps for third-party websites. Having a foreign key to the UserId in the a table will expose the UserId on a GET call, which I've been told that this should be kept secure... right?

Yes. HOWEVER, you should never return your entity from an API. You MUST create a Class (or Anonymous Class) that only contains the properties you want to show. For example, instead of returning the entire User object, use LINQ Select method to select only the safe properties.

Isn't the default security logic template created in such a way that modifying it should be avoided? (Moving ApplicationUser to class Library).

No! The class is there because you may need to modify it (you can add new properties or use it in relationships), and it will not affect the security logic.

To get the logged in user you have to use System.Web.HttpContext.Current.User.Identity.GetUserId();, which I'm not sure about how secure this is in a class library and if this is any good as it uses System.Web, is it common to use this in a class library that should only handle database logic?

This thread may answer your question User.Identity.Name - which assembly reference brings that into your project?. In other situations you pass all the necessary parameters from the asp.net project.

It still requires an correct connection string in web.config, so the database handling still isn't really separated from the MVC application.

Yes, it still requires a connection strings in web.config. It happens because the connection string depends on the starter project. You may have several asp.net projects, that has the same infrastructure, but different databases.

Calling the database correctly for userId should be avoided according to this answer.

Yes, it should! Because (in that case) the UserManager class already has methods that handles the User entity. For example: UserManager.FindById()

In another project I used a third table, which contains additional information about the user, where one string is the e-mail address. This e-mail address is sequel (and unique) to the logged in Username (User.Identity.Name). This third table is only exposed through the API in such a way that it hides the e-mail address. It still requires System.Web.HttpContext.Current.User.Identity.Name; though.

You can add a string property in the user class to hold this information. In your login logic add a new Claim (called email in that case) to the current user. Then, you will be able to access the email of the current user without querying the database. Take a look at this link How to add claims in ASP.NET Identity

Hope it helps!

Community
  • 1
  • 1
Fabio
  • 11,892
  • 1
  • 25
  • 41
  • It really does help Fabio, thanks for your opinions. I see I confused you a bit on the foreign keys part, I ment adding foreign keys to other tables referring to `AspNetUsers` table. Could you, however, elaborate why you choose to include `ApplicationUser` in your class library (or infrastructure)? Pro's and Con's? – CularBytes Aug 14 '15 at 12:43
  • In other tables just put a property of ApplicationUser, run a migration, and EF will take of care of the relationship (creating FKs, etc). This link might be helpful http://forums.asp.net/t/1979169.aspx?How+to+assign+ASP+NET+Identity+User+Id+as+foreign+key+to+another+table+ – Fabio Aug 14 '15 at 14:46
  • This link http://blog.rebuildall.net/2013/10/22/Moving_ASP_NET_Identity_model_into_another_assembly tells how move the asp.net identity to another project. However, you may experience some problems depending on what you want to do. I say this because asp.net identity forces you to follow its patterns (inherited dbcontext, classes, userManager, etc). To honest with you, I don't like asp.net Identity, I prefer create my own membership system, without third-part libraries. – Fabio Aug 14 '15 at 14:57
  • I see that you care about security, and it is good. You can create your own secure membership system. This link teaches how to encrypt passwords https://crackstation.net/hashing-security.htm (there are c# examples at the end). To log the user in, you can use OWIN to handle the cookies / authorization and authentication http://weblog.west-wind.com/posts/2015/Apr/29/Adding-minimal-OWIN-Identity-Authentication-to-an-Existing-ASPNET-MVC-Application http://stackoverflow.com/questions/19091157/how-do-you-login-authenticate-a-user-with-asp-net-mvc5-rtm-bits-using-aspnet-ide. – Fabio Aug 14 '15 at 15:02
  • Thanks for addressing that, There might be a point where I want to do it for myself as well, but I think for now I will let Microsoft do the thinking for me. And FYI: I already knew how to transfer asp.net identity, just didn't know if it was safe. Some answer with FACTS is always welcome stackoverflowers! – CularBytes Aug 14 '15 at 16:45