在我的一个控制器中,我需要使用比角色更精细的方法来保护方法。
我已经创建了MethodSecurityExpressionHandler
,但我无法弄清楚如何访问其中的@Services
。
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, proxyTargetClass = false)
public class CustomMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
@Autowired
ApplicationContext applicationContext;
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
CustomMethodSecurityExpressionHandler handler = new CustomMethodSecurityExpressionHandler();
handler.setApplicationContext(applicationContext);
return super.createExpressionHandler();
}
@Bean
public MethodSecurityExpressionHandler expressionHandler() {
return new CustomMethodSecurityExpressionHandler();
}
}
public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
@Override
protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication,
MethodInvocation invocation) {
final CustomMethodSecurityExpressionRoot root = new CustomMethodSecurityExpressionRoot(authentication);
root.setThis(invocation.getThis());
root.setPermissionEvaluator(getPermissionEvaluator());
root.setTrustResolver(this.trustResolver);
root.setRoleHierarchy(getRoleHierarchy());
return root;
}
}
public class CustomMethodSecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations {
private Object filterObject;
private Object returnObject;
private Object target;
//**This is what I need to work**
@Autowired
private RepositoryService repositoryService;
public boolean canViewFolder(String uuid){
User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return repositoryService.checkFolderPermissions(currentUser.getUsername(), uuid);
}
public CustomMethodSecurityExpressionRoot(Authentication a) {
super(a);
}
public void setFilterObject(Object filterObject) {
this.filterObject = filterObject;
}
public Object getFilterObject() {
return filterObject;
}
public void setReturnObject(Object returnObject) {
this.returnObject = returnObject;
}
public Object getReturnObject() {
return returnObject;
}
void setThis(Object target) {
this.target = target;
}
public Object getThis() {
return target;
}
}
答案 0 :(得分:3)
在CustomMethodSecurityExpressionRoot
中为RepositoryService创建一个setter覆盖CustomMethodSecurityExpressionHandler中的setApplicationContext,以使您在可访问级别传入的applicationContext。
在createSecurityExpressionRoot中使用来自上下文的RepositoryService bean中的applicationContext传递。代码如下。另请注意我对createExpressionHandler()和expressionHandler()所做的更改。在创建ExpressionHandler时,您调用的是super,它只使用默认实现,而不是之前刚刚创建两行的对象。在expressionHandler()中,您正在创建一个新的CustomMethodSecurityExpressionHandler()实例,而不是在createExpressionHandler()中检索您正在创建的实例。
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, proxyTargetClass = false)
public class CustomMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
@Autowired
ApplicationContext applicationContext;
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
CustomMethodSecurityExpressionHandler handler = new CustomMethodSecurityExpressionHandler();
handler.setApplicationContext(applicationContext);
return handler;
}
@Bean
public MethodSecurityExpressionHandler expressionHandler() {
return createExpressionHandler();
}
}
public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
private ApplicationContext applicationContext;
@Override
protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication,
MethodInvocation invocation) {
final CustomMethodSecurityExpressionRoot root = new CustomMethodSecurityExpressionRoot(authentication);
root.setThis(invocation.getThis());
root.setPermissionEvaluator(getPermissionEvaluator());
root.setTrustResolver(this.trustResolver);
root.setRoleHierarchy(getRoleHierarchy());
root.setRepositoryService(applicationContext.getBean(RepositoryService.class);
return root;
}
@Override
protected void setApplicationContext(applicationContext){
super.setApplicationContext(applicationContext);
this.applicationContext = applicationContext;
}
}
public class CustomMethodSecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations {
private Object filterObject;
private Object returnObject;
private Object target;
private RepositoryService repositoryService;
public boolean canViewFolder(String uuid){
User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return repositoryService.checkFolderPermissions(currentUser.getUsername(), uuid);
}
public CustomMethodSecurityExpressionRoot(Authentication a) {
super(a);
}
public void setFilterObject(Object filterObject) {
this.filterObject = filterObject;
}
public Object getFilterObject() {
return filterObject;
}
public void setReturnObject(Object returnObject) {
this.returnObject = returnObject;
}
public Object getReturnObject() {
return returnObject;
}
void setThis(Object target) {
this.target = target;
}
public Object getThis() {
return target;
}
public void setRepositoryService(RepositoryService repositoryService){
this.repositoryService = repositoryService;
}
}