봄에서 부팅 2.1.0는 EvaluationContextExtensionSupport
사용되지 않으며 https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/query/spi/EvaluationContextExtensionSupport.html는 말한다 EvaluationContextExtension 구현 직접
이 단지되지 않습니다하더라도, 그것은 바로이 스택 트레이스이 업그레이드에 실패 시작 :
Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'methodSecurityInterceptor' defined in class path resource [org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; factoryMethodName=methodSecurityInterceptor; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.class]] for bean 'methodSecurityInterceptor': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=methodSecurityConfiguration; factoryMethodName=methodSecurityInterceptor; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [ournamespace/configuration/MethodSecurityConfiguration.class]] bound.
at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:894)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:274)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:141)
...and so on
나는이 추측하고있어 우리가 우리의 현재 코드에서 무슨 일을하는지 단지 부작용 그래서 명시 적으로,이 콩을 대체하지 않습니다. 내가 허용 할 경우 콩과 오버라이드 (override) spring.main.allow-bean-definition-overriding=true
에 따라 https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1-Release-Notes#bean-overriding 나는 단순히 다른 예외를 얻을.
java.lang.IllegalStateException: Duplicate key org.springframework.data.spel.ExtensionAwareEvaluationContextProvider$EvaluationContextExtensionAdapter@10dfbbbb at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133) ~[na:1.8.0_162]
그러나, 나는 심지어 어떤 콩 동작을 재정의하고 싶지 않아, 목표는 다시 봄이 작업에하고자하는 방법을 작동하는 사용자 지정 권한 평가를 얻는 것입니다.
이 마지막 버전에서 작업을했던 방법입니다 :
봄 부팅 2.0.6에서 우리는 일에 우리의 사용자 정의 PermissionEvaluator 클래스를 얻기 위해 다음과 같은했다 :
확장하는 클래스 EvaluationContextExtensionSupport
import org.springframework.data.repository.query.spi.EvaluationContextExtensionSupport;
import org.springframework.security.access.expression.SecurityExpressionRoot;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
public class SecurityEvaluationContextExtension extends EvaluationContextExtensionSupport {
@Override
public String getExtensionId() {
return "security";
}
@Override
public SecurityExpressionRoot getRootObject() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return new SecurityExpressionRoot(authentication) {
};
}
}
그리고 식 핸들러가 우리의 권한 평가자로 생성하고있는 @Bean과 함께하는 클래스 EvaluationContextExtension
import ournamespace.security.CustomPermissionEvaluator;
import ournamespace.security.SecurityEvaluationContextExtension;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.repository.query.spi.EvaluationContextExtension;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
@Configuration
@RequiredArgsConstructor
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
private final CustomPermissionEvaluator permissionEvaluator;
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler =
new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(permissionEvaluator);
return expressionHandler;
}
@Bean
EvaluationContextExtension securityExtension() {
return new SecurityEvaluationContextExtension();
}
}
그리고 마지막으로 우리는 다른 대부분 빈 클래스에서이 있습니다 :
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
...
}
우리는 단지에 넣고 경우 사용자 지정 권한 평가자는 모든 메소드에 적용되지 않은 적이 있기 때문입니다 MethodSecurityConfiguration
클래스입니다. 우리는의 다른없는 구성 아무것도 할 수 있도록 문제의 서버는 OAuth2를 리소스 서버입니다 WebSecurityConfigurerAdapter
. 우리는 또한 우리 자신을 구현 UserDetails
하고 우리는 확장 DefaultUserAuthenticationConverter
이 어떤 식 으로든 새로운 솔루션 관련이있는 경우.
내가 구현하는 시도 EvaluationContextExtension
사용 중단 경고에 명시된 바와 같이, 직접 클래스를. 그것은가 인터페이스를 확장 변경하여 단순한 수정입니다 implements EvaluationContextExtension
. 나는 또한 겉으로는 새로운 패키지로 변경 시도org.springframework.data.spel.spi
나는 우리 자신의 삭제 시도했습니다 SecurityEvaluationContextExtension
및 반환 https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/data/repository/query/SecurityEvaluationContextExtension.html을 직접 콩으로 하지만 어떤 이유로 데이터 패키지는 봄 부팅 2.1.0에서 사용할 수 없음
난 그냥 아예 그 빈의 정의를 제거하려고했습니다.
이 모든 일들이 시작시 다양한 '잘못된 빈 정의'오류가 발생.
마이그레이션 설명서 나이 지금 일에 가정 방법에 대한 다른 자원을 어디서 찾을 수 있는지 아는 사람 있나요?
그냥 참조를 위해서, 실제 CustomPermissionEvaluator
클래스 :
import ournamespace.configuration.Constants;
import ournamespace.exception.InternalException;
import ournamespace.model.Account;
import ournamespace.model.Member;
import ournamespace.model.Project;
import ournamespace.repository.MemberRepository;
import ournamespace.service.ServiceUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import java.io.Serializable;
import static ournamespace.model.MemberStatus.JOINED;
import static ournamespace.model.ProjectRole.*;
@RequiredArgsConstructor
@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {
private final MemberRepository memberRepository;
@Override
public boolean hasPermission(Authentication auth, Object targetDomainObject, Object permission) {
if (targetDomainObject == null)
return false;
if (!(permission instanceof String))
return false;
if (auth == null)
return false;
Account account = ServiceUtil.getAccount(auth);
if (targetDomainObject instanceof Project)
return hasPermissionOnProject(account, (Project) targetDomainObject, (String) permission);
//and so on
}
}
그리고 그것은 사용의 방법에 대한 예 :
public interface ProjectRepository extends PagingAndSortingRepository<Project, UUID> {
@Override
@PreAuthorize("hasPermission(#project, " + Constants.WRITE + ")")
<S extends Project> S save(@Param("project") S project);
}
난 당신의 코드를 가져다가 그것에서 샘플 응용 프로그램을 만들었습니다. 난 여기를 게시 :
https://github.com/jzheaux/stackoverflow-53410526
귀하의 @EnableGlobalMethodSecurity
주석이 켜져 있습니다 WebSecurityConfigurerAdapter
. 또한 확장하는 클래스를 가지고 GlobalMethodSecurityConfiguration
. 이것은 당신이보고있는 =>이 개 무엇을 할 수있는, 시간에 시작할 때 어떤 순서 문제가 발생할 수 MethodSecurityExpressionHandler
의가 생성뿐만 아니라이 개 얻을 EvaluationContextExtension
들.
이것이 바로 내가 당신과 일치하는 경우 또는하지 (나는 그것이 같은데요), 여부 @EnableGlobalMethodSecurity
사용자 정의로 GlobalMethodSecurityConfiguration
, 일이 잘을 시작했다.
또한,하지만, 당신의 정의는 것 같다 EvaluationContextExtension
봄 보안 기본과 매우 유사합니다. 할 수 있다면 봄 부팅을 노출하기 때문에 당신이 때 자동으로 해당 클래스뿐만 아니라 해당 빈 메소드를 제거하는 것이 좋습니다 spring-boot-starter-security
및 spring-security-data
종속있다.