data realted access in authenciation - authentication

I am build a web application,and there are some operations is protected for identified people.
I use the sping security for access control,however I have no idea how to control them when deep to the data level.
For exmaple,there are two operation list and edit operation.
Both the administrator of the company and the administrator of one department can access these operations,but the data they can 'list' or 'edit' are not the same.
administrator of the company can get access to all the data of the company while administrator of one department can only get access to the data of his/her department.
So I wonder what is the best practice to implement these requirements?

Most easy method - use PostFilter annotation on service layer.
#Transactional(readonly=true)
#PostFilter("hasPermission(filterObject, 'edit')")
List<DepartamentData> getDepartamenData();
#Transactional
#PreAuthorize("hasPermission(#data, 'edit')")
List<DepartamentData> editDepartamenData(DepartamentData data);
Or another example:
#Transactional(readonly=true)
#PostFilter(
" hasRole('company_admin')" +
"|| (hasRole('departament_admin') && filterObject.departament.equals(principal.departament))")
List<DepartamentData> getDepartamenData();

Related

Which access control system is right for dynamic multi layer security check?

I have RESTful APIs and in microservice architecture. Such as -
Auth service
User service
Product service
More ...
Currently, I am validating request via JWT token which can be obtained from Auth service. Now, time has come to implement an access control system.
It's an internal tool application (pretty complex) and my primary thought was to use RBAC (Role-based access control) but the application isn't traditional. In application, User A can pair up with another User B and once pair up completed, based on User B's settings User A can perform various action.
So permissions aren't static and they're based on other variables. So should I go for ABAC/PBAC system? Any suggestions?
Thoughts on ABAC
Subjects - Who is sending request e.g User A
Object - Accessing what? e.g Module A
Actions - Read or write? e.g Read GET request
Environment - condition e.g for which User? (User B)
My biased answer is: yes you should :-) (I work for Axiomatics and all we do is PBAC/ABAC and have done so for 15 years).
Note that PBAC and ABAC in this context are the same. PBAC is actually a much older concept. We've been using policies in many places e.g. network access control or SDDL in the past.
The main benefit of attribute-based access control for you (abac) is that it will give you the freedom to adapt your access control policies over time without having to rewrite your application. Effectively, you decouple / externalize authorization from the application.
The following shows the basic architectural flow in ABAC whereby a component (the PEP) intercepts the business flow and converts it into an authorization flow (Can Alice view record 123?).
Policies can be written in xacml or alfa. I prefer the latter since its syntax is super lightweight (read more on Wikipedia).
For instance you could write:
namespace com.acme{
/**
* Tutorial 101 - a flat approach using 4 rules
*/
policyset recordsAccess{
apply firstApplicable
/**
* Records access control
*/
policy records{
target clause object.objectType == "record"
apply firstApplicable
/**
* R1 - A manager can view any records
*/
rule managersView{
target clause user.role == "manager" and action.actionId == "view"
permit
}
/**
* R2 - An employee can view a record in their own department
*/
rule employeesView{
target clause user.role == "employee" and action.actionId == "view"
condition user.department == record.department
permit
}
/**
* R3 - An employee can edit a record they own, if it is in draft mode
*/
rule employeeEdit{
target clause user.role == "employee" and action.actionId == "edit" and record.status == "draft"
condition com.acme.record.owner == com.acme.user.employeeId
permit
}
/**
* R4 - A manager can publish a record if the record is in final
* mode and it belongs to a employee below that manager.
*/
rule managerPublish{
target clause user.role == "manager" and action.actionId == "publish"
condition stringIsIn(stringOneAndOnly(com.acme.record.owner),com.acme.user.subordinate)
permit
}
}
}
}

What if access control rule defined for participant/asset contradicts access control rule for transaction?

I have a question regarding access control.
Specifically, the question is about the relationship between access control rules defined for participants or assets on the one hand and asset control rules defined for transactions accessing those participants/assets.
Here is an example:
Assume a Hyperledger Fabric network is used to create some kind of social network for employees of a company.
The following rule states that an employee has write access to his own data:
rule EmployeesHaveWriteAccessToTheirOwnData {
description: "Allow employees write access to their own data"
participant(p): "org.company.biznet.Employee"
operation: UPDATE
resource(r): "org.company.biznet.Employee"
condition: (p.getIdentifier() == r.getIdentifier())
action: ALLOW
}
Let's assume that the write access is facilitated through a transaction called "UpdateTransaction". Further assume that (maybe by accident) the action value of the access control rule of transaction "UpdateTransaction" is set to "Denied"
rule EmployeeCanSubmitTransactionsToUpdateData {
description: "Allow employees to update their data"
participant: "org.company.biznet.Employee"
operation: CREATE
resource: "org.company.biznet.UpdateTransaction"
action: Denied
}
Now there is the following situation:
Each employee is (through rule 1) given the right to change his/her data.
At the same time employees are not allowed to submit the transaction "UpdateTransaction" to change the data (see rule 2).
Is it now impossible for employees to change their data? Or are employees still able to change their data without submitting the transaction "UpdateTransaction"?
Put differently: is there a way for participants to access data (for which they have access rights) without using any of the transactions defined in the .cto-file?
I think the answer is, it depends.
In your example, denying access to the org.company.biznet.UpdateTransaction transaction would result in org.company.biznet.Employee participants being unable to use that transaction to update their data, even though they would otherwise be allowed.
Having said that, you should keep the system transactions in mind since they provide another potential route for org.company.biznet.Employee participants to update their own data.
For example, I tried that out on the basic-sample-network by replacing the EverybodyCanSubmitTransactions rule with
rule NobodyCanSubmitTransactions {
description: "Do not allow all participants to submit transactions"
participant: "org.example.basic.SampleParticipant"
operation: CREATE
resource: "org.example.basic.SampleTransaction"
action: DENY
}
That business network includes an OwnerHasFullAccessToTheirAssets rule and I was able to use the org.hyperledger.composer.system.UpdateAsset transaction to make updates for participants that owned an asset using the command,
composer transaction submit -d "$(cat txn.json)" -c party1#basic-sample-network
Where txn.json contained,
{
"$class": "org.hyperledger.composer.system.UpdateAsset",
"resources": [
{
"$class": "org.example.basic.SampleAsset",
"assetId": "ASSET1",
"owner": "resource:org.example.basic.SampleParticipant#PARTY1",
"value": "5000"
}
],
"targetRegistry": "resource:org.hyperledger.composer.system.AssetRegistry#org.example.basic.SampleAsset"
}
That wouldn't work if you had locked down the system namespace in your ACL rules though. (ACLs need a lot of thought!)
The other important thing to remember about ACLs is that they do not apply if you use the getNativeAPI method to access data via the Hyperledger Fabric APIs in your transaction processor functions.
Check out the system namespace reference along with the ACL reference, plus there is an ACL tutorial which may be of interest if you haven't seen it.

Cannot remove SID from User Mapping of Login object

During some testing I applied SID value 0x01050000000000051500000085E77E2F11C35F7307E53B2B531D0200 of a system account received from SUSER_SIDfunction to User Mapping of a certain Login object in SSMS. Now based on that I cannot get rid of it as I keep getting an error message Value was either too large or too small for a UInt64 no matter what I enter or erase. I would appreciate if somebody would know how to get rid of a certain User Mapping either via UI or code specially when I encountered such an error message, thank you
Your actions were:
Open login properties of some windows login
Changing the corresponding user for some database to sid (why on the erth did you map the login to the user named as sid???)
This corresponds to the following code:
alter user... with name = [0x01050000000000051500000085E77E2F11C35F7307E53B2B531D0200];
Now you want to do the inverse action, so you need to execute this code:
use CDR_MDS;
alter user [0x01050000000000051500000085E77E2F11C35F7307E53B2B531D0200] with name = NAME=[GROUP\gg ORG RAACO MS BI Team];

How to change Windows ACL 'Group' with Powershell?

Problem:
I need to limit access to a WCF service using only Windows account settings. I have a WCF service with security binding element 'clientCredentialType' set to 'Windows'. Can't change this setting. If I understand correctly, anyone with an authentic windows account is authorized as long as they meet the authorization rules set by the file (EXE) that is hosting that WCF service. So I went into Powershell and queried the settings for that service:
Get-Acl MYSERVICE.exe | Format-List
says:
Path : Microsoft.PowerShell.Core\FileSystem::C:\Program Files (x86)\Blah\Server\MYSERVICE.exe
Owner : BUILTIN\Administrators
Group : MYDOMAIN\Domain Users
Access : NT AUTHORITY\SYSTEM Allow FullControl
BUILTIN\Administrators Allow FullControl
BUILTIN\Users Allow ReadAndExecute, Synchronize
APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES Allow ReadAndExecute, Synchronize
Audit :
Sddl : O:BAG:DUD:AI(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200a9;;;BU)(A;ID;0x1200a9;;;AC)
Every user in my domain seems to have access.
Question, how do I change 'MYDOMAIN\Domain Users' to a different group in my domain so that every domain user (in that group) does not have access?
I have been able to change the list of accounts and their permissions under 'Access' like this:
$perm = "My Other Domain Group","FullControl","Allow"
$rule=New-Object System.Security.AccessControl.FileSystemAccessRule $perm
$myservice_acl.SetAccessRule($rule)
And can presumably explicitly deny or grant access but how do I change the group it inherits from? Or is this the correct approach?
The Windows Security Descriptor(SD) is broken up into four primary parts:
Owner
Group (or Primary Group)
Discretionary Access Control List (DACL)
System Access Control List (SACL)
The Primary Group part of the SD is ignored and has been ignored since Windows 2000 and was preserved for backwards compatability with POSIX operating systems. https://technet.microsoft.com/en-us/library/cc961983.aspx
For your case, the only two fields to concern yourself with are the Owner and the DACL.
The Owner has implicit Full Control over the Securable Object.
The DACL is a list of Access Control Entries (ACEs) which defines Security Identifiers (SIDs or trustees) that have a level of access rights defined.
In other words, if you are concerned about the SD on your service binary, check the owner and all members of the DACL but not the Primary Group.
https://technet.microsoft.com/en-us/library/cc961983.aspx
https://technet.microsoft.com/en-us/library/cc781716(v=ws.10).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/aa379563(v=vs.85).aspx
EDIT: For the sake of completeness, the SACL is a list of ACEs (trustees and access rights) but instead of governing control, it controls who is audited and for what type of behavior.
Group: The security group of the owner.
only users in following groups are able to reach folder\object:
NT AUTHORITY\SYSTEM Allow FullControl,
BUILTIN\Administrators Allow FullControl,
BUILTIN\Users Allow ReadAndExecute, Synchronize,
you should check only access property to add/remove/query who has access to the folder\file
Domain users have access via the local group BUILTIN\Users (joining a computer to a domain automatically adds the group DOMAIN\Domain Users to the group BUILTIN\Users on the joining host). The group property of the security identifier has nothing to do with the access.
If you want to prevent access by domain users in general and allow just a particular domain group you'd remove the DOMAIN\Domain Users ACE and add an ACE for the desired group:
$ace = $myservice_acl.Access |
Where-Object { $_.IdentityReference -eq 'DOMAIN\Domain Users' }
$myservice_acl.RemoveAccessRule($ace)
$ace = New-Object Security.AccessControl.FileSystemAccessRule ('DOMAIN\Other Group', 'FullControl', 'Allow')
$myservice_acl.AddAccessRule($ace)
Set-Acl -AclObject $myservice_acl -Path ...
If you just want to deny access to a particular user you could also create a deny ACE for that user. However, mixing permissions like that tends to become pretty messy pretty fast, so I wouldn't recommend going this route.

How to validate the active directory domain my app is running in?

I have a VB.Net Application that authenticates using the current Windows User without asking for the password. It checks that this user is a member of "MYDOMAIN\ApplicationUsers" before it starts up.
How to check if this is the real domain and not a different one using the same name? Are there any certs or public keys to validate locally? I'd prefer to check this offline, without a third party machine or database etc.
In the System.DirectoryServices.ActiveDirectory Namespace are some Trust an Validate methods but they only seem to check inter domain trust and using a domain name only.
Your problem is that you are using strings and strings like mydomain/application users are not unique across domains. One possibility is to use the SID of the application users group in your expected domain instead of the name. Then you can check the SID of the group to make sure it matches the sid for the expected application users group at run time before checking membership. It would be much harder for a malicious user to spoof domain and group parts of the Sid then the domain and group name.
Ultimately if you are running code on a machine that is owned by the malicious user then this just raises the bar and they could still circumvent this check.
I made some example code which checks the group's SID as Mike suggested. You just need to put your group's SID in the constructor of the SecurityIdentifier class to make the check work against the currently logged on user.
Private Sub DoCheck()
Dim sid As New Security.Principal.SecurityIdentifier("S-0-0-00-0000000000-0000000000-0000000000-000"),
result As Boolean
result = IsUserInGroup(sid)
End Sub
Public Shared Function IsUserInGroup(sid As Security.Principal.SecurityIdentifier) As Boolean
Dim user As UserPrincipal
user = UserPrincipal.Current
For Each group As Principal In user.GetGroups()
If group.Sid.Equals(sid) Then Return True
Next
Return False
End Function
To make the code work you need to import System.DirectoryServices.AccountManagement:
Imports System.DirectoryServices.AccountManagement
This namespace is located in Microsoft's System.DirectoryServices.AccountManagement.dll which is available since .Net 4.0 I believe.