Я пытаюсь ограничить использование 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 разными способами, но ни один из них не работает.