Using Spring Security ACL

2020-06-28 18:49发布

问题:

I am trying to implement Spring Security ACL in my application. I have many classes that I want to use an ACL on.

I read in the documentation that AOP have been used with success before. Does this mean that all the services should have a common interface for doing CRUD against the objects for maximum reuse of the advise?

Or is it normal to manually insert, delete, ... in the save, update, delete methods of the service?

I can't manage to find many examples of how people use the framework.

回答1:

It all depends on your app. Having a centralized hierarchy of services would certainly make it simpler to implement single security checks for create/retrieve/update/delete methods. But you have an existing app with different services that don't necessarily have a common parent implementation, then you'd have to add ALC security annotation on each service method.

Another option is to put ACL security on your DAO layer, it works fine, but for some reason just doesn't feel right. IMHO DAO's shouldn't deal with things like security. I've spent a LOT of time dealing with Spring Security ACL, got a pretty good handle on it by now, ping me if you need any concrete examples.



回答2:

---- Listener for Entity removal (includes cascading deletes) -----

package com.acme.model.aspects;

import javax.annotation.PostConstruct;
import javax.persistence.PreRemove;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.data.domain.Persistable;

import com.acme.PermissionService;

@Component
public class ObjectIdentityListener {

    private static final Logger LOG = LoggerFactory.getLogger(ObjectIdentityListener.class);

    static private PermissionService permissionService;

    @Autowired(required = true)
    @Qualifier("permissionService")
    public void setSearchService(PermissionService _permissionService)
    {
        permissionService = _permissionService;
    }

    @PreRemove
    public void preRemove(Object object) {
        if(object instanceof Persistable) {
            LOG.info("Deleting object identity for class {} id {} ", persistable.getClass(), persistable.getId());
            permissionService.deleteObjectIdentity((Persistable) object);
        }
    }

    @PostConstruct
    public void init() {
        Assert.notNull(permissionService, "'permissionService' is required");
    }
}

---- Delete method for permissionService ----

public void deleteObjectIdentity(Persistable persistable) {
    try{
        MutableAcl acl = (MutableAcl) mutableAclService.readAclById(identity(persistable));
        mutableAclService.deleteAcl(acl.getObjectIdentity(), true);
    } catch (NotFoundException e){
        LOG.info("Could not find ACL for target {}", persistable);
    }
}