Пользовательский PermissionEvaluator для определенных c запросов REST API - PullRequest
0 голосов
/ 17 июня 2020

Я пытаюсь ограничить использование API на основе значения "идентификатор потребителя" в настраиваемом заголовке. Для этого я пытаюсь реализовать собственный PermissionEvaluator. Мой класс конфигурации выглядит как

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
    private final List<TargetedPermissionEvaluator> permissionEvaluators;

    @Autowired
    public MethodSecurityConfiguration(List<TargetedPermissionEvaluator> permissionEvaluators) {
        this.permissionEvaluators = permissionEvaluators;
    }

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler = new DefaultMethodSecurityExpressionHandler();
        methodSecurityExpressionHandler.setPermissionEvaluator(permissionEvaluator());

        return methodSecurityExpressionHandler;
    }

    @Bean
    public PermissionEvaluator permissionEvaluator() {
        Map<String, PermissionEvaluator> map = new HashMap<>();

        // Build lookup table of PermissionEvaluator by supported target type
        for (TargetedPermissionEvaluator permissionEvaluator : permissionEvaluators) {
            map.put("ee34f41c-48ad-4697-a07c-77bc471e34d9", permissionEvaluator);
        }

        return new PermissionEvaluatorManager(map);
    }
}

PermissionEvaluationManger. java

import java.io.Serializable;
import java.util.Map;

import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.access.expression.DenyAllPermissionEvaluator;
import org.springframework.security.core.Authentication;

public class PermissionEvaluatorManager implements PermissionEvaluator {

    private static final PermissionEvaluator denyAll = new DenyAllPermissionEvaluator();
    private final Map<String, PermissionEvaluator> permissionEvaluators;

    public PermissionEvaluatorManager(Map<String, PermissionEvaluator> permissionEvaluators) {
        this.permissionEvaluators = permissionEvaluators;
    }

    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
        PermissionEvaluator permissionEvaluator = permissionEvaluators.get((String)targetDomainObject);
        if (permissionEvaluator == null) {
            permissionEvaluator = denyAll;
        }

        return permissionEvaluator.hasPermission(authentication, targetDomainObject, permission);
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        PermissionEvaluator permissionEvaluator = permissionEvaluators.get(targetType);
        if (permissionEvaluator == null) {
            permissionEvaluator = denyAll;
        }

        return permissionEvaluator.hasPermission(authentication, targetId, targetType, permission);
    }

}

CustomPermissionEvaluator. java

@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {

    public static String[] endPoints = new String[] {"/test1", "/test2"};

    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {

        String permissionString = (String) permission;
        return java.util.Arrays.asList(endPoints).stream().anyMatch(permissionString::contains);.stream().anyMatch(permissionString::contains);


    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        throw new UnsupportedOperationException("Not supported by this PermissionEvaluator");
    }
}

Теперь в моем контроллере я пытаюсь для вызова CustomAuthorization.


    @Override
    @PreAuthorize("hasPermission(#consumerId, '/tes1')")
    public ResponseEntity<ServiceResponse<List>> getList(
        @RequestHeader("consumer-id") String consumerId) {
            // Do something
    }

В приведенном выше коде я хочу ограничить / test1 (getList), чтобы он был доступен для HTTP-запросов с заголовком «consumer-id» как «ee34f41 c -48ad. -4697-a07 c -77bc471e34d9 ". Я жестко запрограммировал некоторые значения, чтобы заставить его работать, но почему-то не работает.

Одна из вещей, которые я заметил, это то, что все мои API начали выдавать HttpStatus как 401.

I Я не уверен, что делаю не так.

Я пробовал вызвать метод hasPermission разными способами, но ни один из них не работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...