I use Identity Server 4 for managing authentication in my different clients.
I'd like include permissions for managing authorization ; to do this, I want to add them on each client and API like suggest [(https://leastprivilege.com/2016/12/16/identity-vs-permissions/)].
I'd like to extend the Client class or ConfigurationDbContext to add roles and permissions but I don't know all steps to do this (what classes I've to extend, how to migrate to EF, what configuration, ... and firstly if it is possible ?)
Thanks
EDIT 1 : answer to mackie
In fact, I don't want to keep roles or permissions in token access as I thought in start, but keep these notions close to my clients because they are directly linked to them (like the article advises)
For example :
client X will define admin and user role (and several permissions for each)
client Y will define superadmin, admin and technician role (but admin for X may have another sense that admin for Y, that's why I want to store them with the client.
Maybe there are other solution but first I thought to modelize with roleClient table with clientId and roleName columns ; and to do this, I'd like to add a property to the Client class by inheritance
EDIT 2 : answer to Ruard van Elburg
I detail the problem I have and why I wanted to extend Client.
I use Code First in my app.
I want to create a list of application roles so I have a one to many relation between a Client which has several AppRoles.
In code first on modelBuilder I can't use this code
modelBuilder.Entity<AppRole>()
.HasOne(x => x.Client)
.WithMany(x => x.XXXXXX) // I can't say a Client has many AppRole as I can't add the property in Client model
.HasForeignKey(x => x.ClientId);
Have you a solution ?
Related
Is it possible to use SQL's Dynamic data masking with Entity framework?
If it is possible, is there any way to combine it with Asp.Identity?
Project I'm working on requires that data is masked for certain user roles and visible to others.
We are using database first approach and Entity framework with data fields masked with:
MASKED WITH (FUNCTION = 'default()')
that need to be visible to admins and remain masked to other user roles. User roles are defined thru Asp.identity.
If it suits well your app architecture you can try approach from this blog post this blog post.
In two words you can create special db user which will represent your "other user roles". And then create two instances of DbContext: one for admin and one for the rest of your roles. So, basically, it's all about user identity provided in connection string.
Correct instance of DbContext with right connection string based on current user you can, for example, provide with dependency injection.
Need suggestion for database for our social network app
So we have a "GroupChat" class where we have an array of "_Users" class objects.
Now in this "_Users" array we want to add invited user aswell.
Example: "John" is a user who invited "Dave/dave#blah.com" but dave is yet to sign up.
But when we open the GroupChat and see the list of users, it should include the invited users as well.
So we are wondering if we should
1.create a new class "InvitedUsers" for invited users or
2.we should directly add invited users to "_Users" class with a flag signedUp=false. And when they signup we check if they already exists and overwrite the data.
Now Problems,
if we create new class "InvitedUsers" then we will have to fetch both the classes everytime which is make the app a bit slow
if we create these invited users directly into user class then parse-server automatically sends email to newly created users(which we dont want to until they sign up)
if we create these invited users directly into user class then we will have to check if the invited user already exists before signing up, if exists then just overwrite. which is doable without any problem?
Thanks
Your question has 2 votes to close as primarily opinion based by now. And indeed the answer is, whatever you like more.
To address your "problems":
I really don't see why this would make your app a bit slower
Well, why don't you adjust your parsing so that the signedUp=false is considered?
Why on earth should that be a problem? That's what databases do all day. Either do it in a transaction, or if your dbms has a built-in functionality use it (like MySQL's INSERT ON DUPLICATE KEY UPDATE)
I'm using Identity Server 4, Asp Identity, EF Core and one database.
I have 3 projects at the moment
IdentityServer - Contains all data contexts and all migrations with my app tables
Api - no context, no migrations however I need to access database somehow from here
Clinet - javascript
The question:
How do I access data context from IdentityServer project and still have all settings (db connection, etc) in one place. I understand I can reference IdentityServer from API and use data context but it seems not right to me. What is the preferred way to do this ?
Since you are interested in this option, I've decided to move my comments to this answer.
First of all, IdentityServer is not the place for your app tables. These are seperate contexts and separate migrations. The preferred way is to maintain the separation of concerns.
As I explained in my answer here, you don't need a relation between the login user and your business context. Instead create a user in the business context. The login user has a different purpose than the business user.
I don't have code for you, but you can take one of the sample apps from IdentityServer. Adjust the API to use your business context. In that context add a user table (which links to the sub claim) and the fields you need for the business context. BTW it doesn't matter if the tables are in the same database, just don't mix the contexts.
In IdentityServer: if the user may register for one website then you can extend the registration form with a drop-down of available websites. Or a list if the user can register for multiple websites.
Now it depends on the chosen strategy. You can wait to register the user in the API, but I think it is far more easy to register the user straight away. There are other options, but here's one where it is part of the IdentityServer configuration (without adding business logic to IdentityServer):
Extend IdentityServer to call the API after registering the user. For this I would add a table in the IdentityServer context with URLs to register per website. When the login user is created, call the configured API(s) to register the business user.
In the API you need to add the method that IdentityServer can call to create the user, linked to the sub claim and including the required user information. This way you can suffice with the sub claim to identify the login user and link this to the business user.
You can use a similar strategy for client apps. Extend IdentityServer with an API method to allow client apps to register users.
If you want to withdraw access, you can delete the login user without having to delete the business user. Which you don't want if you don't want to destroy historical information. You can also use claims to specify if the user has access to the website without having to delete the login user.
Logical Question
Backend implementation
I am implementing User Management Module in Web application. I have three table User, Role and UserInterce. The user table has ManyToMany relationship with role table and Role table has ManyToMany relationship with User Interface table. So whenever Server return user object, the system will verify it's role and that role has access right to which user interface.
this is background overview of backend implementation.
Front End implementation
Whenever user login into the system,server will return user object. I want to implement access control in form basis. e.g. emp role do not have access right to add button where admin role has access right to add button. To implement form based access control i would require to create another table at server side which has information about ui fields and that will be has relationshiop with User Interface table.
can some one provide better way of doing same thing logically ?
If you don't need to have possibility to edditing role's permissions in runtime, the best way is to use spring JSP tag library and build your frontend using spring security tags
http://docs.spring.io/spring-security/site/docs/3.0.x/reference/taglibs.html
Otherwise, using some table for storing your permisssions is the only option to do that
This is more like a question for an advice rather than a precise answer...
In my CakePHP app, I will have backend users and frontend members. They have completely different roles and permissions (users are application managers, members are visitors that register on the website without any access to the application backend). Should I use different tables for these two authorization types, or should I just manage them with a role parameter and bind tables to their profiles depending on it, and why is one solution better than the other?
Use the same table and role or type field. You will have only one login and it will be easy to manage the accounts.
Use ACL or a custom permission system to allow them to different controllers/actions.
For permissions, I have 3 ways to do it :
The strict-role way :
Every role of your application has access to functions with their prefix, but not any other prefix.
Ex : admin has access to admin_edit, but not customer_edit
You add a role varchar or enum in your users table, the routing prefixes in Config/core.php and you allow the access in a AppController::beforeFilter : each role is allowed to access to his prefix only.
The hierarchical way:
Your application's roles are ordered in a hierarchical way, where a role has access to his prefix and every prefixes under him.
Ex : admin has access to admin_edit and customer_edit, but
customer has not access to admin_edit
You add a role varchar or enum in your users table, the routing prefixes in Config/core.php and you allow the access in a AppController::beforeFilter by checking for each $this->request->params['prefix'] which roles can has access to it.
The custom way:
You need your admin to access to some functions, but not all. You need another role to access some functions admin can access, and some functions admin cannot.
Ex : admin can access to admin_edit and customer_edit, but not
customer_create or user_stat. customer can have access to
customer_edit, customer_create and user_stat, but not admin_edit or
user_edit
Use ACL. It's not the easiest way to manage permissions into your application, but if you want specific permissions, it's the best way. So remember this : only use ACL if you really need it.
I agree with cornelb: one table only. Here are some additional reasons:
If you add foreign key constraints, it might be messy to make them refer to both the app managers table, and the visitors table. Always when you want to point to a user, you'd need 2 fields, instead of 1 (a field pointing to the managers table, and one to the visitors table — and exactly one of them has to be null). And what if you need 2 user id fields in a row, with foreign keys? Then you'd suddenly need 4 fields. Simper with all keys pointing to just one table (and user type decided by the above-mentioned field).
Sometimes you might want the user id be part of a primary key — but that's more complicated, if you have two different user id fields, one in each table. Because then the database cannot guarantee that each user id is unique — you'd have to do it yourself at the application level.