1

We have our own db already, with users, roles,userrole tables already in place, and just have discovered the Identity system in .net. I would like to integrate the application cookie authentication but having trouble understanding the different concepts in this Identity model. The OWIN adapter that allows to integrate to third-parties isn't necessarily needed. As we don't need to integrate with third-parties, we just need internal encrypted cookie authentication off our system, that is all we're really looking for.


Can someone help me grasp the concept behind these models? I've read about each of them and still am left confused about them.

Currently I see a number of Identity models: Users, Logins, Claims, Roles

  • Would my roles table use the Roles or Claims model?
  • There are Logins and Users, but we only have one login per user. What would be done in this case?
  • Do I need to use OWIN? I don't need third-party integration, and it looks really heavy.
  • If a user has certain arbitrary properties (avatar, age, etc.), where would this be stored?
  • Any other suggestions on integrating our own table/structure into the Identity model?

The sample tables which the startup app creates are much more complex than needed. Since we don't need many of the features, granted its nice they are already there, but 2-form authentication, sms verification ,etc. all isn't needed. This is an internal system.

I've spent this last week trying to grasp this model and am still having trouble. If someone can point me to the right direction it would be helpful.

RealWorldCoder
  • 1,031
  • 1
  • 10
  • 16
  • If you already have your own things and don't need all the features of Identity, then don't use it. You did specifically state you need the cookie authentication. See the question (which probably contains your solution) and the answer (an alternative way) in [How can I manually create a authentication cookie instead of the default method?](http://stackoverflow.com/questions/7217105/how-can-i-manually-create-a-authentication-cookie-instead-of-the-default-method) – mason Dec 11 '15 at 14:34
  • Also, see my answer [here](http://stackoverflow.com/questions/32589863/windows-authentication-and-add-authorization-roles-through-database-mvc-asp-ne/32590333#32590333) for how to wire your own stuff into the ASP.NET membership system. – mason Dec 11 '15 at 14:35
  • I really like how .net has many methods in place for authorization, so I think it would be a good route to go, rather than spending countless hours trying to re-invent the wheel. There are some complexities which I'm having trouble grasping. – RealWorldCoder Dec 11 '15 at 14:35
  • It's not re-inventing the wheel. It's using the right tool for the right job. If you don't need everything Identity has to offer and you already have your own database schema, then why bother adding it in the first place when there's easier alternatives available that are solid? – mason Dec 11 '15 at 14:37
  • My understanding is OWIN is what makes this a lot heavier than needed. Not necessarily Identity. The reasons I like identity from my understanding are: 1) FormsAuthentication is outdated? 2) I like the global [Allow_Anonymous] filters 3) I like the features offered in the cookie (sliding expiration, encryption) 4) I like the way you can retrieve user data from the context, rather than using a custom model 5) I like how identity has many of the other features in place that make the auth process more seemless – RealWorldCoder Dec 11 '15 at 14:41
  • 1) Forms Authentication is misnamed. It's actually more of a "cookie authentication". It's just that in the early days, the credentials came from someone filling out a form. 2) You can do that with what I provided above. 3) You can do that with what I provided above. 4) Identity does use a custom model. It's just an extension method to retrieve it. You can do that too. 5) But you said you didn't need a lot of them. – mason Dec 11 '15 at 14:44
  • 1) Ms says its outdated so they might retire it, I don't want to be left out in the cold on an upgrade. 2) The global attributes `[Authorize]` conforms with your method? How? 3) Ok. 4) I like how I can just call `User.Identity.Name` to pull out data, rather than having to use other storage ways 5) I don't need 3rd party integration, sms verification, verify code, forgot password, and even register. As it's an internal/private system. I guess it's my understanding that not using this will mostly not allow more of the points I brought up in 2 and 4 – RealWorldCoder Dec 11 '15 at 14:51
  • 1) Cookie authentication will [always be around](http://leastprivilege.com/2015/07/21/the-state-of-security-in-asp-net-5-and-mvc-6-claims-authentication/). 2) Yes, it does. When you give the user an authentication ticket, ASP.NET knows the user is authentication, allowing [AllowAnonymous] and similar attributes to work. And if you use the custom role provider that I described, then the role attributes work too. 4) You do what Identity does. You add an extension method that retrieves the user. For example: `public static MyUserModel GetUser(this IPrincipal principal)`. – mason Dec 11 '15 at 14:55
  • 1) Ok so I'm guessing that Identity uses the same features in place for the original "cookie auth" system? 2) You provided 2 links, which would speak more about the roles? 3) Where can I store arbitrary user properties with this setup? 4) What is the difference between a User, Login, and Principal? Btw thanks for your help this far. – RealWorldCoder Dec 11 '15 at 15:00
  • 1) I haven't specifically looked at it, but I can see the results which tell me "yes" 2) [This one](http://stackoverflow.com/questions/32589863/windows-authentication-and-add-authorization-roles-through-database-mvc-asp-ne/32590333#32590333). 3) You said you already have tables. That's a good place to store it. You can build your model object to contain that information. 4) A user is the generic term for an [IPrincipal](https://msdn.microsoft.com/en-us/library/system.security.principal.iprincipal(v=vs.110).aspx). Login is just another term for the process or act of authenticating a user. – mason Dec 11 '15 at 15:13
  • I see. So do you mostly use just formsauthentication for standard authentication? And OWIN for when you need the extra stuff like 3rd party integration? I know sometimes sticking with backbone stuff is easier to work with, but I didn't want to quite completely ignore OWIN yet without full understanding. Also, would I be able to just grab the avatar using `User.Identity.Avatar` or something like that? If I am able to use `User.Identity.Name` using this method, why would I need a `GetUser` class? Would it just be called upon login? – RealWorldCoder Dec 11 '15 at 15:19
  • It depends on what I'm doing. For internal business applications, I used Integrated Windows Authentications. For the application I'm working on now (a large multi-tenant accounting system) we used forms auth with custom tables. For my personal blog site, I used Identity. It's just a matter of using what's appropriate. OWIN is great for creating modular stuff, and indeed ASP.NET 5's architecture is the next iteration of the concepts introduced with OWIN. If you wanted a user's Date of Birth, store it in the model. Don't store the image in the model though, have an ActionMethod that provides it. – mason Dec 11 '15 at 15:23
  • If you put their avatar image in the model, then every time your retrieve a user from the database, you also have to retrieve all the bytes for the image. So that'd be one thing you'd want to keep separate. But for textual properties like Date of Birth, First Name, Last Name etc, put those in the model, and you get the model via extension method I mentioned which allows you to do something like `var lastName = User.Identity.GetUser().LastName;`. – mason Dec 11 '15 at 15:24
  • `User.Identity.Name` is just a string containing the user name. `User.Identity` is an interface, you can't change it to your own custom type. That's why I'm saying you need an extension method, to obtain your model that has all your custom properties. – mason Dec 11 '15 at 15:26
  • Sorry for confusion, the avatar isn't an image, it's just a gravatar hash string, so its like a property. The `GetUser()` concept makes sense, but there isn't anything already built in that will handle this by adding properties to the user class? After reading the comments to the answer below says I can add properties to my User class. – RealWorldCoder Dec 11 '15 at 15:34
  • If your Avatar is a short Base64 string or a URL to somewhere, then it makes sense as a property. If it was a large byte array, then it would be bad to store it in the model, though you could access it via property (Your property could load the bytes on the fly when called). And no, you can't just add properties to existing types built into the framework, such as IPrincipal. You can however add them to your own User model class. – mason Dec 11 '15 at 15:38
  • But my own user class would not automatically go into the pipeline would it? Only IPrincipal class is recognized into the pipeline? And by pipeline I actually mean the `User.Identity` class thats available in requests – RealWorldCoder Dec 11 '15 at 15:40
  • Correct, it doesn't automatically go into the pipeline. That's where the extension method comes in. You don't *have* to use an extension method, it just makes it easier to access it. If you want to see custom forms authentication (but not roles) in an application, I did a demo project for a job interview, you can see the login logic [here](https://github.com/mason-mcglothlin/masonogcrm/blob/master/src/WebApp/Controllers/UserAccountController.cs#L88). It also makes use of the `[AllowAnonymous]` attributes etc. – mason Dec 11 '15 at 15:44
  • Nice. Where is the `Repository` class, I couldn't find it. This class basically handles all the storage for the logins? – RealWorldCoder Dec 11 '15 at 15:51
  • Also, I'm guessing maybe I should start with just FormsAuth as a prerequisite to understand these concepts before I further dig in to Identity – RealWorldCoder Dec 11 '15 at 15:52
  • Repository is stored in a separate class library. Navigate up the folder structure, then down into the other class libraries. Also, I chose *not* to use an extension method to get my user account model since I didn't need to access it very often and wanted to get it via a repository I injected. You can see what that looks like [here](https://github.com/mason-mcglothlin/masonogcrm/blob/master/src/WebApp/ApiControllers/NotesController.cs#L47). – mason Dec 11 '15 at 15:54

1 Answers1

2

Users are pretty straight-foward, so we'll skip that. Logins are external authentication attachments. Based on the way Identity works with third-party authentication providers, you can have logins with no attached users, users with no attached logins, or users with attached logins. It's the difference between be authenticated with your site (login) and being an register member of your site (user).

Claims are just data associated with a user. Generally, these are going to be transient - things which don't make sense to be stored in perpetuity on the user For example, third-party auth tokens that expire would not make sense to be actually saved to the user in a database.

Roles are just permission sets. People go different ways with roles, but technically speaking, a role just defines some ability a user may have, like "CanEdit", "CanView", "CanDelete", etc. You'll often see people use them more as groups: "Admin", "Editor", "Contributor", etc., which abstractly define user permissions.

OWIN is a core component of Identity. It's not really something you can pick or choose. If you don't want to use the third-party auth functionality, then don't, but having it included is not an issue.

Finally, Identity is rather opinionated. It's possible to migrate your user data into Identity-specific constructs, but it would be virtual impossible to have Identity just use your existing user tables in place. I'm not sure if that's what you actually meant, but if it is, forget about it. You can customize the individual Identity models to include more information in the database, but generally, you'll need to find a way to map your data into what Identity provides if you want to use Identity.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • Thanks for your answer. To clarify.. 1) If I was to use cookie authentication, would that be considered a login? or would that just be part of the user? 2) If I don't need both user/login features, then how about the db tables that the app expects to handle the request, are these omitted from the db? Will app layer understand this? 3) Would claims handle the arbitrary properties of a user (avatar, age, etc)? 4) I understand I would have to bring in my tables in some way to conform to the identity model, but what you're saying is not with my current set-up. Can you explain this more please? – RealWorldCoder Dec 11 '15 at 14:55
  • 1) Cookie auth is a separate concept. Both your regular site login (user) and external login (login) would utilize an auth cookie to function. The difference is merely whether they're just authenticated or a full-fledged "user" that's authenticated. The authentication status itself has nothing to do with either table. 2) You might be able to get rid of some of the tables, but I wouldn't worry about it. Simply having a table in a database has no effect on anything. If you don't use it, you don't use it. – Chris Pratt Dec 11 '15 at 15:15
  • 3) The exact opposite. Things like avatar, age, etc. should be properties on your user class. They are not transient and equally applicable to every user. Claims should be used when the data is transient and/or no universally applicable. A Facebook auth token, for example, is only applicable to users who login with a Facebook account. That's a claim. 4) That's basically what I mean. You'll need to look at the schema of the tables generated by Identity and figure out the mapping between your existing tables and that, adding additional properties to Identity models as needed. – Chris Pratt Dec 11 '15 at 15:18
  • 1) Ok, so the fact that cookieauth is provided by OWIN, it still wouldn't require a login? Login is only for external logins and not for internal ones? 2) I already have 2-3 of these tables, maybe structured a bit differently, but the rest of them can be called other names? I simply don't like the fact it has AspNetTableName in my db. 3) Ok, so in my case I wouldn't even need Claims? Since no external or third-party access is allowed 4) If I have my own structure already, I would have to change that to conform with Identity, or will Identity conform to at least some of my current tables? – RealWorldCoder Dec 11 '15 at 15:27