We are trying to implement Custom Role membership provider for our web app. For authorization we want to check for one more field like Facilityid for the logged on user along with role he has. eg. my User1 having Role1 with Facility1 can access some option and same user role for Facility2 have different option. So is there a way we can extend the existing role/profile provider to authorize user with this additional field along with role assigned.
Depending on how complicated you expect this to be you might want to just have Facility1 and Facility2 be roles, even though they may share a lot of the same aspects. In this manner, you should not need to extend the membership provider.
There can be n facilities so having those many roles does not look fesiable. If we can find a way by which we can pass the Facilityid from the application to this security module roleprovider and fetch appropriate role for user only for that facility.
Related
I am creating one multi-tenant app in Laravel with Single Database and thinking to use laravel-permission package by spatie.
My Requirement is pretty straightforward, I want my tenants to create their own Roles, whereas permissions will be managed by Super Admin only.
My problem is when I was trying using, It worked for 1st client but 2nd time it gives error:
A role 'Admin' already exists for guard 'admin'.
As I mentioned client can create roles, so they can crate duplicate roles.
Please recommend better approach or package or should I try writing custom code.
Any help appreciated!
Because the name is indexed in the role table, you cannot create a duplicate role name, I ask you not to change the package, but in case you have 2 ways to handle this
1- unindex the name collemn or disable unique feature, and add you tenant id to table so by do this you can manage and get right role for each tenant
2- add another table to manage your sub role (tenant role) and connect you sub role with master role by id
I would consider using a hidden prefix: on the roles and permissions that would scope them to a particular tenant. So for example:
Roles
system:admin
tenant_a:admin
tenant_b:admin
Permissions
system:creates-roles
system:reads-roles
tenant_a:creates-roles
tenant_a:reads-roles
The prefix would not be assignable by a Tenant, the system would automatically assign that based on the User. However, if you're a System Admin (i.e. Super Admin) then you could create/view/assign a prefix in order to manage the roles and permissions.
This would require you to write some custom logic for handling the prefix, however, it is pretty flexible (you could nest unlimited identifiers - a:b:c:d:e etc.) and doesn't require you to go messing with any underlying packages (i.e. laravel-permissions).
I have the following use case:
Users have general roles like:
devteam
this will give them access to several functions in the backend.
But additionally they also have a non-fix set of roles which may be added during time. Something like
devteam-europe (composite role to devteam role)
devteam-asia (composite role to devteam role)
etc.
Now I want the backend functions to behave like this:
Access function if role is "devteam": that works :)
But in the underlying sql queries I want to restrict the resultset depending on other roles. So devteam-europe will get other results as devteam-asia.
The big problem is, that in my applicaton each team has a uuid, while in KeyCloak the role has a speaking name. So I need to map somehow
devteam-europe to my internal UUID!
I could add attributes or properties to the role in KeyCloak, but they don't seem to be available in the JWT.
In my real world project it's a multi-tenancy applicatio with various entities.
Do you have any ideas, on how to to accomplish this?
Cheers Maik
I could add attributes or properties to the role in KeyCloak, but they don't seem to be available in the JWT.
In the corresponding client, you must define a Token Mapper which will tell Keycloak what source (in your case attribute or property) will map to which target (key => value) in your JWT.
Since I had problem with Passport multi auth, I wonder is it necessary to have an admin guard (and an admins table) or it's better to use the default guard (and users table) for both admins and users with the help of role and permissions? Which is better?
That's a really hard question to answer without more information, but I'll try looking at it from a few perspectives:
You have an application that has users that can turn into admins (and vice-versa)
In this situation, I would probably have a single table that contains an is_admin column and use the column to validate whether the user can perform administration tasks (e.g. by using Laravel's gates). The downside to this is that if you wanted to create a third type of user (e.g. supervisor), you would need to change the model used.
You have an application where users are completely separate from administrators
If you control the administrators and everyone else is just a user, creating separate guards could be used, this does allow for a lot of flexibility in the future if you wanted to implement different authentication flows for both administrators and users (for example, using SAML). If you were to add a third type of user (e.g. supervisor), you could then just create another guard.
You have an application that can have different (customisable) permissions for each user
In this case I would recommend implementing a roles table, a permissions table, a role_permissions table and adding a column called role_id to the user table. This provides the most flexibility and is also usable with the Laravel's gate system, but is probably the most difficult to setup and hardest to maintain.
For the application I develop, we use a mixture of roles and guards. We use roles for users as each user gets a customisable set of permissions. We then use a separate guard for API users which inherit the permissions of the user they were authenticated with.
CRM 2015: I want to be able to create a role for local IT to be able to add user accounts and assign roles.
Regarding the 'adding roles' portion, is it simple enough just to create a role for local IT to 'write' to 'security' roles in the'business management' tab of 'security roles' at the user level?
No, this is not that simple. User cannot give another user privilege higher than he has (it would be a serious security hole). So for example you have role to edit Security roles and you have Read access for Accounts in your Business Units. If somebody in your Business unit has no Read access and only User access, you can add him Read access for Business Unit (the same you have), but you will not be able to give him Organizational access (so higher than yours). You could imagine that if this would be possible, you will be able to basically give yourself Admin privilege and do whatever you want in CRM.
Knowing that, it should be possible for you to create a role that for example have full access to Accounts, Contacts, Custom entities etc. and Security Roles. This role would be able to modify other users access levels to Accounts, Contacts etc. but no other entities that they don't have privilege to.
Exactly the same logic applies to assigning the Security Roles. So user A cannot assign a Security Role to user B, if it gives user B privileges higher than has User A.
In the end, it is very hard to properly implement the scenario that you described, because there are so many privileges and user needs to have a lot of them to even use the CRM. I've tried this once but could not satisfy the business requirement - it always ended up with using System Admin role, because there was always some scenario that could have not been handled by a user only with this "specific" security modification role.
Assigning 'System Administrator' security role and changing Access Mode in user record to 'Administrative' helped me to achieve this. User still cannot access any transaction data. So, I think you can go for this approach.
In my application I need to register users. The users can be any of three: admin, client and general. They have different attributes (Admin may have only name, client may have company address and so on). The default MVC membership scheme is okay but how can it be extended to register more information during registration time? Or should I use custom membership?
I need to have a record of clients and general users with clientID or generalID.
The default MVC membership scheme is okay but how can it be extended
to register more information during registration time? Or should I use
custom membership?
I think too many people, yourself included, are expecting to get too much from the default ASP.NET Membership Provider. It was never designed to handle application-specific things, like what company your customer works for, your admin's name, and so on. It's main purpose is storing passwords for authentication.
Sure, the password needs to be linked to a username, so that there can be a 2-key authentication pair. Sometimes you also need the user's email address, when it is different from their username, in order to contact the user regarding their password. But don't store anything else about your users in the membership store. Store it in your application database.
In order to join data between your application and the membership provider, use the membership provider's UserName or ProviderKey as a column in one of your database tables. You end up with 2 entities which are not explicitly related. You can even have your SqlMembershipProvider implemented in a separate database from your application database. Even if they are in the same database, avoid having a foreign key between any of the provider tables and your application tables. This muddies the waters between what you own, and what you "outsource" to the membership provider.
You end up with 2 physically isolated representations of your user. One is the MembershipProvider, which contains a password for your user. The other is your application, which contains other business-specific details. The two are only logically associated within your application. After you authenticate a user with the membership API, their UserName and/pr ProviderKey become available to your application. You can then use that piece of data to query your app database and get the additional details. This is where you might put something like the clientID or generalID you mentioned.
If you look at the System.Web.Security.Member* API, this should make things clearer. It does one thing really well -- associating your users with passwords and other information related to password resetting (like the email address, question and answer, etc). So outsource just the password provider, and rely on your application to do the important stuff.
You could customise the default profile provider or create your own... Follow this reference
http://msdn.microsoft.com/en-us/library/8zs47k7y
You can add new properties to the profile for anything in the web.config too
I highly suggest creating your own membership roles. It's dead simple and nothing can beat the flexibility of having your own implementation.
Here's a video I made a while back showing you step by step how to achieve this:
http://www.youtube.com/watch?v=BsxUsyMSGeA
The gist of it is, you create your own AuthorizeAttribute and create your own roles; protecting each controller or even individual Action methods along the way.
The one drawback of this approach is that you can determine what Role a user has in your system, but not what a Role can do in your system. Does that make sense?
There are other choices if you need to edit what a role can do at runtime.