Spring acl @PreAuthorize для разрешения на запись, всегда запрещающего (403) с AccessDeniedException - PullRequest
1 голос
/ 31 октября 2019

Просто чтобы узнать ACL, я пробовал с конфигурацией 4 таблиц acl. У меня есть таблица проекта (объект домена), я хочу достичь некоторой безопасности на уровне объекта домена. Он отлично работает с чтением объектов домена и отфильтровывает список, как и ожидалось
mask=1 и `

@PostFilter("hasPermission(filterObject, 'READ')")
public List<ProjectVO> listProject();

Выполнено: администратор может видеть все проекты, менеджер проектов может видеть проекты, для которых онэто менеджер ... Я не мог столкнуться с какой-либо проблемой с @PostFilter и READ

Но я изменил метод проекта, как указано ниже

@PreAuthorize("hasPermission(#project, 'WRITE')")
public void modifyProject(Project project);

Это всегда дает мне AccessDeniedException какприведенные в журналах ниже

DEBUG - @org.springframework.security.access.prepost.PreAuthorize(value=hasPermission(#project, 'WRITE')) found on specific method: public void com.pvn.mvctiles.service.impl.ProjectServiceImpl.modifyProject(com.pvn.mvctiles.model.Project) 
DEBUG - Caching method [CacheKey[com.pvn.mvctiles.service.impl.ProjectServiceImpl; public abstract void com.pvn.mvctiles.service.ProjectService.modifyProject(com.pvn.mvctiles.model.Project)]] with attributes [[authorize: 'hasPermission(#project, 'WRITE')', filter: 'null', filterTarget: 'null']] 
DEBUG - Secure object: ReflectiveMethodInvocation: public abstract void com.pvn.mvctiles.service.ProjectService.modifyProject(com.pvn.mvctiles.model.Project); target is of class [com.pvn.mvctiles.service.impl.ProjectServiceImpl]; Attributes: [[authorize: 'hasPermission(#project, 'WRITE')', filter: 'null', filterTarget: 'null']] 
DEBUG - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@fec7843d: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_USER 
DEBUG - Checking permission 'WRITE' for object 'org.springframework.security.acls.domain.ObjectIdentityImpl[Type: com.pvn.mvctiles.model.Project; Identifier: 1]' 
DEBUG - Executing prepared SQL query 
DEBUG - Executing prepared SQL statement [select acl_object_identity.object_id_identity, acl_entry.ace_order,  acl_object_identity.id as acl_id, acl_object_identity.parent_object, acl_object_identity.entries_inheriting, acl_entry.id as ace_id, acl_entry.mask,  acl_entry.granting,  acl_entry.audit_success, acl_entry.audit_failure,  acl_sid.principal as ace_principal, acl_sid.sid as ace_sid,  acli_sid.principal as acl_principal, acli_sid.sid as acl_sid, acl_class.class from acl_object_identity left join acl_sid acli_sid on acli_sid.id = acl_object_identity.owner_sid left join acl_class on acl_class.id = acl_object_identity.object_id_class   left join acl_entry on acl_object_identity.id = acl_entry.acl_object_identity left join acl_sid on acl_entry.sid = acl_sid.id  where ( (acl_object_identity.object_id_identity = ? and acl_class.class = ?)) order by acl_object_identity.object_id_identity asc, acl_entry.ace_order asc] 
DEBUG - Fetching JDBC Connection from DataSource 
DEBUG - Returning false - no ACLs apply for this principal 
DEBUG - Voter: org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter@71322d20, returned: -1 
DEBUG - Voter: org.springframework.security.access.vote.RoleVoter@30750dc0, returned: 0 
DEBUG - Voter: org.springframework.security.access.vote.AuthenticatedVoter@69e7d03e, returned: 0 
TRACE - Returning cached instance of singleton bean 'delegatingApplicationListener' 
TRACE - Returning cached instance of singleton bean 'delegatingApplicationListener' 
TRACE - Failed to complete request 
org.springframework.security.access.AccessDeniedException: Access is denied
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:65)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.sun.proxy.$Proxy259.modifyProject(Unknown Source)
    at com.pvn.mvctiles.controller.ProjectController.modifyProject(ProjectController.java:70)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

acl содержание таблицы
enter image description here

Я не мог понять, что не так. Мои конфигурации

Внедрение GlobalMethodSecurityConfiguration
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class AclMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration
{
    @Autowired
    MethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler;

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler()
    {
        return defaultMethodSecurityExpressionHandler;
    }
}
MethodSecurityExpressionHandler конфигурация компонента
@Configuration
public class AclConfiguration
{
    @Autowired
    DataSource dataSource;

    @Bean
    public MethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler()
    {
        DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
        AclPermissionEvaluator permissionEvaluator = new AclPermissionEvaluator(aclService());
        expressionHandler.setPermissionEvaluator(permissionEvaluator);
        return expressionHandler;
    }

    @Bean 
    public JdbcMutableAclService aclService() 
    { 
        return new JdbcMutableAclService(
          dataSource, lookupStrategy(), aclCache()); 
    }

    @Bean
    public AclAuthorizationStrategy aclAuthorizationStrategy() 
    {
        return new AclAuthorizationStrategyImpl(
          new SimpleGrantedAuthority("ROLE_ADMIN"));
    }

    @Bean
    public PermissionGrantingStrategy permissionGrantingStrategy() 
    {
        return new DefaultPermissionGrantingStrategy(
          new ConsoleAuditLogger());
    }

    @Bean
    public EhCacheBasedAclCache aclCache() 
    {
        return new EhCacheBasedAclCache(
          aclEhCacheFactoryBean().getObject(), 
          permissionGrantingStrategy(), 
          aclAuthorizationStrategy()
        );
    }

    @Bean
    public EhCacheFactoryBean aclEhCacheFactoryBean() 
    {
        EhCacheFactoryBean ehCacheFactoryBean = new EhCacheFactoryBean();
        ehCacheFactoryBean.setCacheManager(aclCacheManager().getObject());
        ehCacheFactoryBean.setCacheName("aclCache");

        return ehCacheFactoryBean;
    }

    @Bean
    public EhCacheManagerFactoryBean aclCacheManager() 
    {
        EhCacheManagerFactoryBean ehcm = new EhCacheManagerFactoryBean();
        ehcm.setShared(true);
        return ehcm;
    }

    @Bean
    public LookupStrategy lookupStrategy() 
    { 
        return new BasicLookupStrategy(
          dataSource, 
          aclCache(), 
          aclAuthorizationStrategy(), 
          new ConsoleAuditLogger()
        ); 
    }
}
...