Spring @弹簧内自动接线许可评估器
首先,我在谷歌上搜索了大量信息,虽然似乎有一个修复程序,但我无法成功地在Spring @弹簧内自动接线许可评估器,spring,spring-security,spring-aop,spring-boot,Spring,Spring Security,Spring Aop,Spring Boot,首先,我在谷歌上搜索了大量信息,虽然似乎有一个修复程序,但我无法成功地在许可评估器中引用注入的@Bean: public class MyPermissionEvaluator implements PermissionEvaluator { private static final Logger LOG = LoggerFactory.getLogger(MyPermissionEvaluator.class); @Autowired private UserRe
许可评估器中引用注入的@Bean
:
public class MyPermissionEvaluator implements PermissionEvaluator {
private static final Logger LOG = LoggerFactory.getLogger(MyPermissionEvaluator.class);
@Autowired
private UserRepository userRepo;
@Override
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
if (authentication == null || !authentication.isAuthenticated()) {
return false;
}
if (permission instanceof String) {
switch((String) permission) {
case "findUser":
return handleUserPermission(authentication, targetDomainObject);
default:
LOG.error("No permission handler found for permission: " + permission);
}
}
return false;
}
@Override
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
throw new RuntimeException("Id-based permission evaluation not currently supported.");
}
private boolean handleUserPermission(Authentication auth, Object targetDomainObject) {
if (targetDomainObject instanceof Long) {
boolean hasPermission = userRepo.canFind((Long) targetDomainObject);
return hasPermission;
}
return false;
}
}
在该期的评论部分,Rob Winch提供了一个变通建议
要解决此问题,可以使用LazyInitTargetSource代理permissionEvaluator
尽管如此,我在实现发布的XML的基于注释的JavaConfig版本时遇到了问题我正在使用Spring Boot 1.0.0.BUILD-SNAPSHOT和Spring Boot starter安全性。
我有一个类来配置方法安全性,如下所示:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(new MyPermissionEvaluator());
expressionHandler.setParameterNameDiscoverer(new SimpleParameterDiscoverer());
return expressionHandler;
}
}
以及许可评估器的开始:
public class MyPermissionEvaluator implements PermissionEvaluator {
private static final Logger LOG = LoggerFactory.getLogger(MyPermissionEvaluator.class);
@Autowired
private UserRepository userRepo;
@Override
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
if (authentication == null || !authentication.isAuthenticated()) {
return false;
}
if (permission instanceof String) {
switch((String) permission) {
case "findUser":
return handleUserPermission(authentication, targetDomainObject);
default:
LOG.error("No permission handler found for permission: " + permission);
}
}
return false;
}
@Override
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
throw new RuntimeException("Id-based permission evaluation not currently supported.");
}
private boolean handleUserPermission(Authentication auth, Object targetDomainObject) {
if (targetDomainObject instanceof Long) {
boolean hasPermission = userRepo.canFind((Long) targetDomainObject);
return hasPermission;
}
return false;
}
}
需要做什么才能从任务前评估器
中获取对我的用户存储库的引用?我尝试过各种变通方法,但没有成功。似乎无法将任何内容@自动连接到许可评估器中
。无法将任何内容自动连接到使用new…()
创建的对象中(除非您使用的是@Configurable
和AspectJ)。因此,您几乎肯定需要将您的PermissionEvaluator
拉入@Bean
。如果您还需要将其设置为惰性代理(因为Spring Security初始化的顺序敏感性),那么您应该添加@lazy@Scope(proxyMode=INTERFACES)
(或者TARGET\u CLASS
,如果这更适合您)。我也有同样的问题,Dave Syer的答案对我来说非常有效。为了响应jasonfungsing的评论,为了将PermissionEvaluator拉入一个Bean,我用@Component注释了我的自定义类,并将DAO自动连接到其中:
@Component
public class CustomPermissionEvaluator implements PermissionEvaluator{
private CustomRepository customRepository;
@Autowired
public void setCustomRepository(CustomRepository customRepository) {
this.customRepository = customRepository;
}
@Override
public boolean hasPermission(Authentication authentication, Object target, Object permission) {
if (target instanceof ...
然后,在我的GlobalMethodSecurity配置覆盖类中,我创建了PermissionEvaluator类的一个私有实例变量,@将PermissionEvaluator自动连接到该类中,并在我的setPermissionEvaluator方法调用中使用该实例(从而避免了“新”调用):
我不需要使用@LAZY或@SCOPE注释。Dave Syer&SchonWieder的解决方案适合我。作为替代方案,我想展示一下我以前是如何解决这个问题的。我像匿名类一样在MethodSecurityConfig中注入权限计算器
@配置
@EnableGlobalMethodSecurity(Prespenabled=true)
公共类方法SecurityConfig扩展了GlobalMethodSecurityConfiguration{
@自动连线数据源;
@凌驾
受保护的MethodSecurityExpressionHandler createExpressionHandler(){
DefaultMethodSecurityExpressionHandler expressionHandler=新的DefaultMethodSecurityExpressionHandler();
setPermissionEvaluator(新PermissionEvaluator(){
@凌驾
公共布尔hasPermission(身份验证身份验证、对象targetDomainObject、对象权限){
JdbcTemplate=新的JdbcTemplate(数据源);
...
如果(计数=1){
返回true;
}否则{
返回false;
}
}
@凌驾
公共布尔hasPermission(身份验证arg0、可序列化arg1、字符串arg2、对象arg3){
//TODO自动生成的方法存根
返回false;
}
});
返回表达式处理程序;
}
}
对于未来的用户:
根据@Dave Syer的建议,问题正在使用new关键字将new MyPermissionEvaluator()更改为@Autowired将解决问题,如下所示
更改以下代码
发件人:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(new MyPermissionEvaluator());
expressionHandler.setParameterNameDiscoverer(new SimpleParameterDiscoverer());
return expressionHandler;
}
}
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Autowired
private MyPermissionEvaluator myPermissionEvaluator;
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(myPermissionEvaluator);
expressionHandler.setParameterNameDiscoverer(new SimpleParameterDiscoverer());
return expressionHandler;
}
}
至:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(new MyPermissionEvaluator());
expressionHandler.setParameterNameDiscoverer(new SimpleParameterDiscoverer());
return expressionHandler;
}
}
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Autowired
private MyPermissionEvaluator myPermissionEvaluator;
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(myPermissionEvaluator);
expressionHandler.setParameterNameDiscoverer(new SimpleParameterDiscoverer());
return expressionHandler;
}
}
通过上述更改,下面的代码将按预期开始工作
@Autowired
private UserRepository userRepo;
这很有道理。今天早上我将修改代码并发回!谢谢嗨,戴夫·赛尔,我也有同样的问题。您能解释一下如何在java注释中配置更多关于“您几乎肯定需要将PermissionEvaluator拉出到@Bean中”和“由于Spring安全初始化的顺序敏感性”,谢谢您必须添加,您仍然需要使用@组件对evaluator类进行注释