首先,我已经广泛搜索了这一点,虽然似乎有一个固定的地方我无法成功引用@Bean
内注入的PermissionEvaluator
:
在该问题的评论部分,Rob Winch提供了有关建议的工作
要解决此问题,您可以使用LazyInitTargetSource代理您的permissionEvaluator
话虽这么说,我在实现发布的XML的基于注释的JavaConfig版本时遇到了麻烦。 我正在使用Spring Boot 1.0.0.BUILD-SNAPSHOT和spring-boot-starter-security。
我有一个类来配置方法安全性,如下所示:
@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;
}
}
PermissionEvaluator
的开头:
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;
}
}
我需要做什么才能从UserRepository
内部获得对PremissionEvaluator
的引用?我尝试了各种变通方法,但没有成功。 @Autowired
......
PermissionEvaluator
答案 0 :(得分:9)
无法将任何内容自动装入使用new ...()
创建的对象中(除非您使用@Configurable
和AspectJ)。因此,您几乎肯定需要将PermissionEvaluator
拉出@Bean
。如果你还需要使它成为一个惰性代理(因为Spring Security初始化的排序敏感性),那么你应该添加@Lazy @Scope(proxyMode=INTERFACES)
(或TARGET_CLASS
,如果这更适合你)。
答案 1 :(得分:7)
我有同样的问题,Dave Syer的答案对我来说非常合适。为了回应jasonfungsing的评论,将PermissionEvaluator拉入Bean我用@Component注释我的自定义类,并将@Autowired 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 ...
然后在我的GlobalMethodSecurityConfiguration重写类中,我创建了一个PermissionEvaluator类的私有实例变量,@ Perutired PermissionEvaluator并在我的setPermissionEvaluator方法调用中使用了这个实例(因此避免了" new"调用):
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration{
private DataSource datasource;
private CustomPermissionEvaluator customPermissionEvaluator;
@Autowired
public void setCustomPermissionEvaluator(CustomPermissionEvaluator customPermissionEvaluator) {
this.customPermissionEvaluator = customPermissionEvaluator;
}
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(customPermissionEvaluator);
return expressionHandler;
}
我不需要使用@LAZY或@SCOPE注释。
答案 2 :(得分:0)
Dave Syer& Sons的解决方案SchonWieder为我工作。作为我想要展示的替代方案,我之前是如何解决这个问题的。我在MethodSecurityConfig中注入Permision Evaluator,就像匿名类一样。
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration{
@Autowired DataSource dataSource;
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(new PermissionEvaluator(){
@Override
public boolean hasPermission(Authentication auth, Object targetDomainObject, Object permission) {
JdbcTemplate template = new JdbcTemplate(dataSource);
...
if (count==1){
return true;
} else {
return false;
}
}
@Override
public boolean hasPermission(Authentication arg0, Serializable arg1, String arg2, Object arg3) {
// TODO Auto-generated method stub
return false;
}
});
return expressionHandler;
}
}
答案 3 :(得分:0)
根据@Dave Syer的建议问题,使用 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;
}
}
以下更改代码将按预期开始工作。
@Autowired
private UserRepository userRepo;