I'm trying to figure out the correct way to implement and code the following using desing patterns, or a good object oriented solution:
There is an user class which can contains a variable set of permits, each one enables him to do different action on the application. The idea is to be able tell a certain user object to, for example delete an order, if he has any permits that enable him to do so, do it and if not, to raise an exception.
If someone has a place where to read about this, it's helpfull too.
thanks
There are built in functions for permission in C#/.NET.
The access requirements on a function is set through the PrincipalPermissionAttribute class, or inside the code with PrincipalPermission. To prevent a method from being called unless the current user is a member of the Administrators role, the following attribute is used (sample from MSDN):
[PrincipalPermission(SecurityAction.Demand, Role = "Administrators")]
static void CheckAdministrator()
{
Console.WriteLine("User is an administrator");
}
Both these checks against the current identity of the calling thread. So what you need to do is to implement the IPrincipal interface to allow your users to be set as the thread identity. Then you can use standard .NET PrincipalPermission to check security. It works exactly as you want - if the security demand is not met, an exception is thrown.
If one user can have multiple permits, each permit allows different execution tasks, then you might wanna have a look at decorator pattern.
although it depends a lot on your requirements.
Related
I'm using EF Core 3.0 and I like to implement a ABAC system to control rights in my app. To do it I'd like to do all the permissions stuff in just one layer and control it using some decorators in the controllers. The idea is to follow a bit this example. I think using the new UseAuthorization method will be also helpful.
I am still designing the solution and I have an issue: currently in my controllers I have functions such as (the AuthorisationFilter is not implemented yet, it's precisely where I'm working on)
// GET api/project/:id
[HttpGet("{projectId}")]
[AuthorisationFilter]
public async Task<ProjectDTO> GetProjectById(int projectId)
{
return await this.projectService.GetProject(projectId);
}
and I also have some others that return all projects:
// GET api/project/projects
[HttpGet("projects")]
[AuthorisationFilter]
public async Task<IEnumerable<ProjectDTO>> GetAllProjects()
{
return await this.projectService.GetAllProjects();
}
Now, in my first case, my authorization filter should simply consider according to some attributes if a certain user is able to access this project or not. Clear.
However, in the second case, it could be that one user can see some projects and a different user can see some different projects, and I don't know exactly what my authorisation filter should return. Allow or deny? If I deny, I lose control of what happens next.
I understand the authorisation filter is not the place to create the conditions to generate the SQL query, but I don't like either to simply accept the action and lose control of the permissions. In other words: if there is a bug in the implementation of GetAllProjects which returns more projects than the authoirised ones, I should not send these projects to the user.
Hence: how should the authorisation layer work? Should I filter there the valid projectId's and then call GetAllProjects with this list as an argument?
In a nutshell: is there a way put all the rights control in a single layer?
Authorization layer should provide details about what the user can do, but enforcing that is up to the individual components.
Your ProjectService need to know what the user is authorized to do and enforce it.
If your authorization layer decides that, it can become very involved in pretty much everything your application does, as it need to know way too much about each controller action or the database access, or whatever else which will not be very maintainable.
What if one of your services decides to access a 3rd party service over a 3rd party SDK?, it would make sense for your ..say MyTwitterService to enforce that rather than a generic authorization layer.
Usually you pass in the context of the user (usually some sort of "rights" the user has) and the ProjectService will decide what things to return. (or fail if the rights are insufficient or invalid).
I have an application that needs to load data via web service calls and perform various permission and data checks. Fairly typical. I'm currently doing this in the background when the application starts, however it is a wizard type application and so the user can't do much until all of this has completed. If any issues come up when doing this I want to present the user a helpful message (you are "missing permission x" or "failed to retrieve y").
For the following, understand that I can change how I'm going about doing something, but I can't change what steps I need to perform. This has been simplified down as well.
A typical item might go like this. I need to retrieve a list of groups the user belongs to. However, first I need to check if the user has permission to view this list of groups otherwise the other call will fail. Once I have the list, I then need to check whether they have certain permissions within each item and discard those that don't apply. If they don't have permission in any of the groups, inform the user.
Initially I had everything in a LoadAndCheck() type call to work out all the various items I needed. Obviously this is large an clunky.
I then moved to a breaking each step up into pattern where each item was in a class behind an interface
interface IInitialize {
bool InitializeAction();
void OnFailure();
}
(i.e. CheckThisPermission, LoadThisList, CheckThatPermission). Each class performed a small action and if that action failed (loading data) or was false (permission check) it contained the step to perform to inform the user of the issue.
I can then loop through these classes and on failure of one step, not perform the following steps and have things configured to inform the user. This also lends itself to DI down the road if I settle on this pattern.
However, something just doesn't feel right about this pattern, though it is better than everything in one big call. Maybe it's just the name I'm giving to things. However my brain is wiped out and I'm not coming up with anything better.
So do you have any good patterns for doing something similar when starting up your application?
I personally have a SecurityManager static class that i call methods on for checking certain types(groups/items/users/etc) with methods such as
HasTradePermission(PermissionType type, User user, Trade trade);
HasInvoicePermission(PermissionType type, User user, Invoice invoice);
Only inside this method do I start calling the is part of group/what group/ does this group have this and this permission etc, so as far as the application is aware, all it interacts with is 'HasPermission' objects, therefore in my app i just iterate over e.g. Trades, and call the HasTradePermission.
Inside these has permission object, i would get the list of groups that the user is part of and check if there is a match with one of the groups inside the TradePermissionGroups etc..
some time ago we implemented impersonation into our application (a DMS system). We did this because the users should not have access to the physical files of the document pages.
So the user logs into our application, gets impersonated to a special user so he can access the files he needs from within our application.
When this impersonation was planned we didn't think that it would be a great thing: The user impersonates one time and everything is fine. We implemented the code into the existing methods where it was needed (just sth. like Impersonation=true or Impersonation=false).
This was wrong: Impersonation had to set off and on on several places (for example, when the user wants to send a document as an email you have to set impersonation off to use the user's mail profile) so whenever we add a new functionality we have to test with and without impersonation.
Because I have additional functionality to implement I would like to extinct this behaviour to get a clean approach. But I don't really have an idea what could be best approach.
First thing that comes into my mind would be the state pattern, but this would result in an impersonated class and a not-impersonated class for all classes where impersonation takes effect. This would increase the number of classes.
Other thing would be method pointers: When using impersonation call impersonated version of function, else call not-impersonated version of function.
This would lead to more methods. Better than state pattern approach? I don't think so.
So, what would be your approach to get a clean solution?
(I already thought about using threads but this seems to be very complicated)
Hope you can help me.
Regards,
inno
Sounds like a crosscutting aspect - maybe aspect oriented programming?
Well one option would be to define what the default behavior should be such as impersonation on for the user. This default behavior would happen at time of login to the system. When the user performs other behaviors in the system such as sending a document as email this could be encapsulated in a service where the service takes the user as an argument and then uses the impersonation necessary for that feature. To take your example:
var emailService = new emailService();
//inside the service call it would apply the impersonation necessary for the operation
emailService.send(user, new Attachment(documentToSendViaEmail));
Say I have a database containing Books and Users and these users have certain permissions on books(like editing, deleting, etc.). Now I would write methods like the following and expose this as both an API and WebService.
[WebMethod]
Book GetBook(User login, int id) {
if (!CheckLogin(login))
throw new Exception("Login error");
return new Book(id);
}
This seems all fine, but how would I save this book again when I modified it? It feels right to put a Save() method on the Book object, since it(the object) should take care of itself. But the permissions checking doesn't feel right there. (I don't want the Book object to know anything about users)
Should I create SaveBook(Book book) like methods to do this?
Is it anyway a good idea to check this way if some user has some permission? For a WebService I could imagine it's okay, but I have doubts about this being used as normal API(Assembly).
You have stumbled across something called Cross-Cutting-Concerns... things in your app that have to work together but logically belong separated. Logging is another common example.
Aspect Oriented Programming (AOP) offers a good pattern for separating concerns such as security from business objects. On .Net, PostSharp is a commonly used AOP facility.
It seems to me that you are defining services.
You are not really dealing with individual books more with the set of Books or maybe a Library, which would offer services such as
addBookToLibrary( ... details ...)
borrowBook( Book)
returnBook ( Book )
findBooks ( ... search criteria ... )
reserveBook ( Book, User, for how long)
Now, it should be clear that different categories of user will be authorized to use different methods, Librarians can do more that Members.
This implies that for each request we need to know who is calling. Often that authenticated identity is available in some kind of context that is passed invisibly to each methoid. [That's why I didn't put the user id as an explicit parameter, except in reserve() ... why did I do that?].
I think it's reasonable for both Web Services and APIs to have authorisation rules for methods such as these.
Web method can use .Net membership engine, that (by default) create auth cookies. So at next call you need just to check if user already logged in.
Also remember about standard Authorization web service, that do it for you.
Having the Save() method on Book sounds like a merging of concerns, one object being responsible for too much.
When you call Save(), as you rightly have identified, numerous things have to occur, including permission checks. Additionally, the question is raised as to exactly where the Book instance is being saved. A cleaner design would involve creating a new class to be responsible for the loading and saving of objects and handling permission checks as part of the process. I recommend you do a bit of reading around the Repository Pattern, as it could be a good fit for your particular scenario.
You should always check permissions where security is a concern. Making the assumption that a higher level component will protect you will come back to bite you, especially when you are exposing functionality as services and APIs! If you wish to use the .NET role-based security system, you can use the PrincipalPermission class (or its attribute equivalent) to demand that your current user in the necessary group(s). This will throw a security exception if the current principle is not permitted to perform the action.
I would expect to see permission-related exceptions thrown from methods where the calling user did not have the correct permissions, as they clearly identify the reason for the exception. This makes developing against the API or service much easier.
Whoever is calling your API or service can be expected to perform their own checks to ensure the principal has the correct permissions before allowing them to initiate an action which could result in a permission-related exception being thrown in production code.
Is it possible to use AzMan for role based authorization on objects which are created at runtime? If yes how can this be done?
For Example:
If an object of class "CustomAlert" is created at runtime, I am trying to see if I can have different rules for different objects of the class "CustomAlert". If an object is created by using a specific user's identity, More permissions are available for that user considering him to be CREATOR/OWNER of the object. Only the creator/owner can modify the object.
It is certainly possible to use AzMan for this. I have implemented several applications with this form of resource and role based security. AzMan is actually VERY flexible, and I've also implemented a resource hierarchy (think Windows file system security), with custom users and groups and full inheritance of roles throughout the hierarchy, along with the ability to deny operations at any level. To do this you need to understand AzMan Scopes.
AzMan Scopes allow you to create individual role/operationsets for a particular resource. This resource can be anything you choose, it's just a string identifier to AzMan. These roles/operations are in addition to any application level assigned roles.
The way I've implemented it previously is to use the object's id as the scope name. Ideally for simplicity this should be a GUID (though it does make the MMC application very messy), but equally you could use a "type-id" format i.e. "CustomerAlert-1" (much friendlier in MMC app). When performing an AccessCheck in azman, you pass the scope name to AccessCheck (at the moment it only takes a single scope, even though the AccessCheck definition allows an array).
I'll run through an example of how to do this (for anybody else struggling) ...
Create operations such as
CustomerAlertView,
CustomerAlertEdit,
CustomerAlertDelete at the
application level.
Create a role
definition called CustomerAlertOwner
at the application level.
Add all
the operations to the CustomerOwner
role.
In your app, create a Scope
called "CustomerAlert-1".
Create a
Role Assignment called "Owner" on
the scope.
Add the CustomerAlertOwner
role definition to the "Owner" role
assignment.
To this Owner role, add
the customer/user "Dave".
Now when
you do an access check in say
DeleteCustomerAlert(), you simply
pass the id of the
CustomerAlertDelete operation and
the type/id of the object that you
want to delete as the scope i.e.
"CustomerAlert-1"
For object property-based access checks (i.e. locking out read/write of certain properties), there are 2 approaches I can think of .. first is to assign operations in the objects scope for each property and access type i.e. PropertyNameGet, PropertyNameSet, PropertyAddressAdd. You can simplify this by creating the operations at the application level and using tasks/role to group commonly used permission sets. The other way is to use the scope for each property (CustomerAlert-1-Name), but this would be messy and is not as efficient, as you'll need to separately load multiple scopes when accessing a given object.
You should bear in mind that you cannot explicitly deny an operation in AzMan, you just don't assign a role for the user in the application/scope. This means certain types of resource hierarchies (groups/users) etc. can be more difficult ot implement.
If you need any further help with AzMan, feel free to ask .. I've covered most scenarios.
Azman supports role-based security but it's based on roles only - not on ACLs. If a particular user is logged in, then they have specific permissions based on who they are, but these permissions are just static values - they could be made to apply to all objects of a given type, but not differ according to specific attributes of particular instances of that type.