Seb*_*oek 8 java spring spring-security spring-boot
在Spring Boot 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
Run Code Online (Sandbox Code Playgroud)
我没有明确地覆盖这个bean,所以我猜这只是我们在当前代码中所做的一个副作用.如果我spring.main.allow-bean-definition-overriding=true根据https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1-Release-Notes#bean-overriding允许bean覆盖,那么我只是得到另一个例外.
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]
Run Code Online (Sandbox Code Playgroud)
但是,我甚至不想覆盖任何bean行为,目标是让Spring自定义权限评估器再次按照Spring的意图工作.
这是它在上一版本中的工作方式:
在Spring Boot 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) {
};
}
}
Run Code Online (Sandbox Code Playgroud)
然后是一个使用我们的权限评估程序创建表达式处理程序的类,以及一个带有a的@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();
}
}
Run Code Online (Sandbox Code Playgroud)
最后我们在一个基本上是空的类中有这个:
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
...
}
Run Code Online (Sandbox Code Playgroud)
这是因为如果我们只是将它放在MethodSecurityConfiguration类中,自定义权限评估程序从未应用于所有方法.有问题的服务器是oauth2资源服务器,所以我们不配置其他任何东西WebSecurityConfigurerAdapter.如果这与新解决方案有任何相关性,我们也会实施我们自己的UserDetails扩展DefaultUserAuthenticationConverter.
我已尝试EvaluationContextExtension直接实现类,如弃用警告中所述.通过将extends接口更改为只是一个简单的修改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作为bean但由于某种原因,Spring Boot 2.1.0中没有数据包
我试过完全删除那个bean的定义.
所有这些都会导致启动时出现各种"无效的bean定义"错误.
有谁知道在哪里可以找到迁移指南或任何其他资源,了解它现在应该如何工作?
仅供参考,实际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
}
}
Run Code Online (Sandbox Code Playgroud)
以及如何使用它的示例:
public interface ProjectRepository extends PagingAndSortingRepository<Project, UUID> {
@Override
@PreAuthorize("hasPermission(#project, " + Constants.WRITE + ")")
<S extends Project> S save(@Param("project") S project);
}
Run Code Online (Sandbox Code Playgroud)
我接受了您的代码并从中创建了一个示例应用程序。我把它贴在这里:
https://github.com/jzheaux/stackoverflow-53410526
您的@EnableGlobalMethodSecurity注释已打开WebSecurityConfigurerAdapter。您还有一个扩展GlobalMethodSecurityConfiguration. 这有时会在启动时导致一些排序问题,这可能就是您所看到的 =>MethodSecurityExpressionHandler创建了两个EvaluationContextExtensions以及创建了两个s。
无论情况是否确实如此(我猜是这样),当我将您的@EnableGlobalMethodSecurity与您的 custom相匹配时GlobalMethodSecurityConfiguration,事情开始得很好。
此外,您的自定义似乎EvaluationContextExtension与 Spring Security 的默认设置非常相似。如果可以,您可能会考虑删除该类以及相应的 bean 方法,因为 Spring Boot 会在您拥有spring-boot-starter-security和spring-security-data作为依赖项时自动公开一个。
| 归档时间: |
|
| 查看次数: |
3030 次 |
| 最近记录: |