env: Asp Core, Entity-framework
In my system I have two types
[Table("User")]
ApplicationUser : IdentityUser<Guid>
[Table("Customer")]
Customer : IdentityUser<Guid>
Both entities(Customer and User) have many different fields, what makes using only one table in a Database not correct. And both entities must have possibility to do sign in.
As I found ASP Net can have only one identity setup.
Question: What is the best way or best practices to make this stuff work?
I suggest you not try to mix or unify Identity of application user and meanings of application user from another boundary contexts of you application.
Identity record of application user is his representation from security perspective, and it is used for identification/authentication of user. So it contains user security data, its access roles and other security claims. Any Identity record can have very specific access right based on his roles and claims and usually it is enough.
If you need to represent application user from another perspective (as your employ, or as you customer, maybe as guest record, etc.) then it is better to create another table (Employees, Customers, Guests , etc.) for it in another DbContext (not in Identity context). It will give you possibility not to mix their conceptual borders. Who knows, maybe at some moment you will decide to create separated microservices for each boundary context and Identity will serve them all as another microservice.
If you asking now yourself how to organize such parallel storing of interpretations of the same application user, then there are different approaches. But for example:
When user is registering you create Identity for him
When he is logged-in he use his Identity data for authentication
But when he create his first order you create Customer record for him that has same Id as his Identity, or has foreign key to Identity, or... the rest depends on your needs and business logic.
Related
I would like to ask you for clarification when integrating IdentityServer 4 with ASP.NET Identity.
I am working with two database contexts.
Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityDbContext<IdentityUser> and IdentityServer4.EntityFramework.DbContexts.ConfigurationDbContext.
Identity Server 4 is using AspNetIdentity .AddAspNetIdentity<IdentityUser>().
So IdentityUser has assigned IdentityUserClaims and it's properly reflected in JWT token after successfull authentication.
Question now is, what is with the IdentityResource and IdentityClaim:UserClaim from IdentityServer4 ConfigurationDbContext? As claims are now used from aspnet identities, this entity is not used at all. Am I right?
Another question is how ApiScopeClaims are now in game? They are still used by the Identity Server because of ApiScope for which token is issued for. Right? But now it's up to me to keep in sync ApiScopeClaim and IdentityUserClaim which are from different db contexts.
Last Question is regarding IdentityRoles and IdentityRoleClaims which are not the same as IdentityUserClaims. What's the idea behind? In my idea, role is grouping of claims for specific business role for easier management, therefore role should not define new claims but reference set of IdentityUserClaims. Additionaly, I created role, assigned to user, corresponding claim types assigned to scope and result is that - claims which are assigned to role and user has this role are not included in JWT. Why?
Thank you for your answers.
IdentityResource is a category or grouping of claims. Each IdentityResource can have many IdentityClaims which are references to actual the claims held in AspNetUserClaims. The built in IdentityResources are openid and profile.
ApiScopeClaims are part of the hierarchy of Api Resources (as opposed to the identity resources mentioned above.)
ApiResource --has many--> ApiScopes --has many--> ApiScopeClaims.
Adding a claim type to an ApiScopeClaim will attach an AspNetUserClaim (if one exists) to the access_token when when the User makes a request to that ApiScope.
An IdentityRoleClaim (i.e. AspNetRoleClaim) is just a bit a information you can tack on regarding a particular role; it does not related to a User, but just to the role itself.
Sound like you want to create an IdentityResource for your logical grouping of claims, and then define those claim types in IdentityClaims. But you would need a way to first find out the user's role in order to request the appropriate IdentityResource in scope parameter. Or implement one of the IdentityServer interfaces like IProfileService to do this kind of work on the IdentityServer instance.
I'm currently developing a full web client administration system on Symfony2. However, the question whether to create a User entity and a separate Client entity or have the User entity manage all client information (like it's credit state) remains unanswered.
From what I've gathered, using a separate entity for each thing permits me to have a better separation between the login system (which needs a User entity with basic properties) and the bussiness logic (which needs a Client entity with all the properties a client in the real world has). However, that would mean having a bigger footprint (if they were saved in a database, I would have to use a join statement) than having a single entity contain all properties.
What would you recommend in this case? Is there anything I'm missing?
For the user login and system you can use FOSuserBundle
If your clients also need to login in same system then i would say that you go for
https://github.com/netmeansnet/NmnMultiUserBundle/blob/master/Resources/doc/index.md
Then you can have separate class for each type os users and define custom properties
They all will use same basic attributes like username , password and then you can have extra information for client Enitity
I am starting a new ASP.Net MVC 3 app and I'm hoping to be able to use the built in Membership provider.
The issue I have is that my application can be used by various organizations and it is important that the information shown is only applicable to the organization the user is working for.
The no brainer approach would be to insist all users use their email addresses as their username so everyone is unique and can be associated with their respective organizations. The problem is, some users don't have email addresses so there is no reliable way of ensuring unique names and I don't want people to know the Usernames already in use by different organizations. (USernames should only be unique to the Organization, not the entire app)
Ideally, I would want the User to enter their organization name in one field, then their username in another (and then the password!)
So we could have Jane login from one organization.....
Organization Company1
Username Jane
Password ********
and then someone else also called Jane could login from a different organization..
Organization Company2
Username Jane
Password ********
So my question is, what is the best way of modifying the Membership system to allow for this extra field?
I'd go about writing a custom MembershipProvider to suite the requirement.
http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx
The provider pattern used by membership is designed so that you can extend it. You can inherit from the default provider and from the default membership use class to add the fields you need. This saves you from having to write a provider from scratch. As #mare pointed out, there are potential pitfalls though.
I would overcome these by perhaps having a login form that prompts for organisation, username & password, but behind the scenes combine the org & username & use that as the internal username.
The built-in (default ASP.NET) membership provider does not provide a concept of an Organization/Company/Firm or Department. You will have create your own tables in the database for those with a foreign key to the aspnet_users table to be able to store that additional information (I wouldn't go changing the default aspnet_users table because it might make it incompatible with the current default provider or future ones). You will then need to use the default provider for the default functionality and create a Service class to support the extended functionality. I know, I have done it. It gets complicated and dirty, takes time but it's completely doable.
Most likely you will end up creating your own provider and that starts with the requirement to support Users in Companies. In case you thought that changing the default provider to support that wouldn't be necessary. The requirement about uniqueness within the company is another one you will have to implement.
I think there is a built in option in the membership. look into the APPLICATION field in table my_aspnet_users.
reference here:
http://msdn.microsoft.com/en-us/library/system.web.security.membership.applicationname.aspx
From what i have read from this paper
I understand that a role based access control system is one where users can be assigned to roles where roles specify permissions to perform operations on objects
But in asp.net we do not specify "Operations on objects", what i mean here is that how can we specify "All users in Role R can perform a delete on object O"
Where is the Object Part in ASP.Net
The security model is asp.net is pretty limited. In essence you only have control at the Role level. Which means that for any operation you have to test to see if the user is any of the roles that you want to allow that operation to be performed.
We took the path of defining our own model that gives much more granularity. Basically we define operations and assign those operations to various roles. This way we can test if they have a "delete account" right versus testing if they are in "Admin", "Account Admin", or any number of other roles. It's very similar to how Active Directory works. Further it allows us to reconfigure roles as needed.
There is a piece called Authorization Manager (AzMan) that ships with windows. It can work with your membership provider to provide operation level control. Some people have had success with it, but others have complained that it's difficult to get working. We used it about 5 years ago on a project and at that time it worked about 95% of the time. The other 5% it had communications issues with our AD controller.
Which leads us to your question: Is the built in ASP.Net membership provider a true role based access control system? No. It allows you to define Roles, not operations.
Check out rhino security if you need something more fine grained.
As suggested in previous posting, to achieve more granularity you would need to build up on the existing ASP.net membership and role providers. There are third party controls such as http://www.visualaccesscontrol.com that provide role based Module Access Security and Data Access Security as well. With Visual Access Controls you can add administrative functionalities to your ASP.net web application to dynamically restrict the users to the activities they are allowed to perform and the subset of data they are allowed to see based on their respective roles.
You are implementing the delete operation, so it is up to you to check if the logged in user has permission to delete the object. For example, you might create a role "CanDeleteOs". Then, your code would look like this:
if ( !Roles.IsUserInRole("CanDeleteOs") )
throw new Exception("User does not have permission to delete O's.");
I've got a generic ASP.NET (MVC) application, that uses NHibernate as the model persistence layer, and ASP.NET Membership/role/profile services as the user management layer.
The question is what can be considered as the best practice to create linkings between the domain data and the users. (For example is I want to create a forum system I want to link each topics/posts to a specific user, and want to display the user at each request).
These are the posiibilites I've been thinking of:
Store the user ID in NHibernate (like having a Guid column in all your domain classes (Posts, Topics etc.) that needs to reference a User) and use GetUser each time you need the name of the user from the guid (which might result in n+1 queries)
B variant: Alternatively store the user name too.
Use the same database, and create a read-only NHibernate maintaned domain object User, that maps to the same data as the M/R/P services do.
Forget about M/R/P and create a separate user management service based on NHibernate
Forget about both and use J2EE/RoR/merb/DJango/etc. (please don't pick this option :) )
other...
I would go for step 2 (almost, as it does not necessarily needs to be readonly) and create a custom membership provider for NHibernate.
To save time you can use an existing one like the one from Manuel Abadia.
With that you keep the full power of NHibernate (lazy loading, etc.) and enjoy M/R/P services too.
There is also a NHibernate based Membership provider at CodePlex
4 guys from rolla have an excellent post if you want to buil your own provider on top of the asp.net membership API : https://web.archive.org/web/20211020114106/https://www.4guysfromrolla.com/articles/110310-1.aspx