It is best to verify that the AUTHORIZATION user is AUTHORIZED to access the resource - Spring mvc, Spring Security, Hibernate

We have spring mvc rest api using spring security and sleep mode for MySql db.

We have certain roles. For instance:

Standard user: ROLEA

Superuser : ROLEB

Currently, to provide an authenticated user authorized to access / update a specific resource, we are doing something like this:

Identify the current authenticated user:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String activeLogin = authentication.getName(); 

Define the login associated with the object they are accessing:

 String loginAssociatedToRequestedEntity = fooService.getEntityA(EntityAId).getEntityB().getEntityC().getLogin(); 

Compare the user associated with this resource with the active login:

 if (!loginAssociatedToRequestedEntity.equals(activeLogin)) { throw new ForbiddenAccessException(); } 

I have a number of problems with this, some of them include:

  • Very wasteful ... each entity must be hydrated / populated. This can be even worse than the above example if the object to be accessed is further from the table with the login names.
  • Looks like the smell of code (Law of Demeter).
  • A query may appear that may update multiple objects. A similar verification of the above may need to be repeated.

I considered the following options:

Spring acl

Apache shiro

So my question is, is there a better way to make sure that the authenticated user is authorized to access a specific resource, that is, does not allow them to access another user's resource in the same role.

If you could give a concrete example (github) that would be very appreciated.

TIA.

+5
source share
2 answers

While role membership checks are more of an anti-pattern (it is better to encode permission or action), they are usually used for service level access control (web requests and method calls), but generally not suitable for protecting real domain objects in the configuration with multiple tenants, for example, to prevent a user from accessing another user's resource of the same role.

Your approach to checking whether an authenticated login will be associated with a specific domain object will work, but it is cumbersome, fumes and / or pollutes your application data model with a security data model and, as you suspected, is not best practice.

You have already defined some parameters:

Apache Shiro provides a consistent and easy-to-use API that supports access control for domain objects, but you are responsible for providing a β€œkingdom” backend, which means you may have to implement your own data warehouse and / or DAO.

Spring Security ACL is the Spring Access Control paradigm for securing domain objects. It separates the security data model from your application data model. Access control lists make it easy to provide or verify access to domain objects by adding or searching ACLs, but you may need to write your own DAO if you want to efficiently find all the domain objects that the user has access to (for example, to represent these objects on the list or deny access to them). In addition, you are responsible for maintaining ACLs because:

Spring Security does not provide any special integration to automatically create, update, or delete ACLs as part of your DAO or repository operations. Instead, you will need to write code [...] for your individual domain objects. You should consider using AOP at your service level to automatically integrate ACL information with service level operations.

- Spring Security Link 4.0

Finally, you will need to configure the ACL implementation if the default API is incompatible with your application model (for example, if your domain objects do not have open getId() or do not use long compatible identifiers)

If you are not married to Spring or Shiro to provide access control to a domain object, there is another alternative:

OACC , an open source Java security infrastructure (disclosure: I am a proponent and co-author) that provides a rich API to enforce and manage your authorization requirements. OACC is a complete access control framework with a rich API that does not require a DIY implementation to provide software and dynamic simulation of fine-grained authorization. It features a fully implemented RDBMS-enabled data warehouse for its security model, which the API manages for you behind the scenes.

The OACC security model is permission based: it essentially manages permissions between resources. Resources represent both protected domain objects and their subjects (i.e., Items). It also provides efficient query methods for finding resources by resolution without first loading all the resources and then filtering out unauthorized ones. These methods are symmetrical in the sense that you can find both resources for which a particular resource has a specific set of permissions, and resources that have a specific set of permissions for a specified resource

Compare the OACC snippet to provide permission below with sample code from Spring Security ACL Link>:

 // get the resource representing the principal that we want to grant permissions to User accessorUser = Users.findByName("Samantha"); Resource accessorResource = Resources.getInstance(accessorUser.getId()); // get the resource representing the object that we want to grant permissions to Resource accessedResource = Resources.getInstance(Foos.findById(44).getId()); // Now grant some permissions Permission permission = ResourcePermissions.getInstance("ADMINISTER"); oacc.grantResourcePermissions(accessorResource, accessedResource, permission); 

To check the authorization, you can call

 oacc.assertResourcePermissions(accessorResource, accessedResource, permission); 

or check return value

 oacc.hasResourcePermissions(accessorResource, accessedResource, permission); 

Another new feature of OACC is creation permissions, which not only control what resources entities can create, but also precisely determine what permissions they will receive on a new resource after its creation - they are determined once, permissions are automatically assigned to the creator of the resource, without the need for explicit API calls.

Therefore, OACC was specifically designed using your case of using authenticated fine-grained authentication.

+7
source

You can use Spring Data JPA to add <basic Spring security information to your SQL queries. Example:

https://github.com/spring-projects/spring-data-examples/blob/master/jpa/security/src/main/java/example/springdata/jpa/security/SecureBusinessObjectRepository.java

You can also use a database like PostgreSQL 9.5, Oracle VPD or SQL Server 2016 that have Row Security

0
source

Source: https://habr.com/ru/post/1244438/


All Articles