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类进行注释