有没有办法在@Preauthorize块中创建更具表现力的语句?这是我重复的例子,因为@Preauthorize并非开箱即用。
@RequestMapping(value = "{id}", method = RequestMethod.DELETE)
public void deleteGame(@PathVariable int id, @ModelAttribute User authenticatingUser) {
Game currentGame = gameService.findById(id);
if(authenticatingUser.isAdmin() || currentGame.getOwner().equals(authenticatingUser)) {
gameService.delete(gameService.findById(id));
} else {
throw new SecurityException("Only an admin, or an owner can delete a game.");
}
}
我想要的是类似的东西。
@RequestMapping(value = "{id}", method = RequestMethod.DELETE)
@Preauthorize(isAdmin(authenicatingUser) OR isOwner(authenicatingUser, id)
public void deleteGame(@PathVariable int id, @ModelAttribute User authenticatingUser, @ModelAttribute currentGame ) { //I'm not sure how to add this either :(
gameService.delete(gameService.findById(id));
}
问题的一部分是,我需要查询数据库以获取其中一些内容以验证权限,例如查询数据库以获取游戏副本,然后将游戏所有者与制作人进行比较请求。我不太确定所有这些如何在@Preauthorize注释处理器的上下文中运行,还是不确定如何将东西添加到@Preauthorize(“”)value属性中可用的对象集合中。
1)首先,你必须重新实现MethodSecurityExpressionRoot
,其中包含额外的方法特定功能。最初的Spring Security实现是程序包私有的,因此不能仅对其进行扩展。我建议检查给定类的源代码。
public class CustomMethodSecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations {
// copy everything from the original Spring Security MethodSecurityExpressionRoot
// add your custom methods
public boolean isAdmin() {
// do whatever you need to do, e.g. delegate to other components
// hint: you can here directly access Authentication object
// via inherited authentication field
}
public boolean isOwner(Long id) {
// do whatever you need to do, e.g. delegate to other components
}
}
2)接下来,你必须实现MethodSecurityExpressionHandler
将使用上述定义的custom CustomMethodSecurityExpressionRoot
。
public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
@Override
public void setReturnObject(Object returnObject, EvaluationContext ctx) {
((MethodSecurityExpressionRoot) ctx.getRootObject().getValue()).setReturnObject(returnObject);
}
@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;
}
}
3)在你的上下文中定义表达式处理程序bean,例如,通过XML,你可以按以下方式进行操作
<bean id="methodSecurityExpressionHandler"
class="my.package.CustomMethodSecurityExpressionHandler">
<property name="roleHierarchy" ref="roleHierarchy" />
<property name="permissionEvaluator" ref="permissionEvaluator" />
</bean>
4)注册上面定义的处理程序
<security:global-method-security pre-post-annotations="enabled">
<security:expression-handler ref="methodSecurityExpressionHandler"/>
</security:global-method-security>
5)然后在你的@PreAuthorize
和/或@PostAuthorize
注释中使用定义的表达式
@PreAuthorize("isAdmin() or isOwner(#id)")
public void deleteGame(@PathVariable int id, @ModelAttribute currentGame) {
// do whatever needed
}
还有一件事。使用方法级安全性来保护控制器方法不是很普遍,而是使用业务逻辑(也就是你的服务层方法)来保护方法不是很普遍。然后,你可以使用以下内容。
public interface GameService {
// rest omitted
@PreAuthorize("principal.admin or #game.owner = principal.username")
public void delete(@P("game") Game game);
}
但是请记住,这仅是示例。它期望实际的主体具有isAdmin()
方法,并且游戏具有getOwner()
返回所有者的用户名的方法。
如何计算方面中的Spring Security表达式?我想我可以很容易地使用完成这项工作的类I spring框架
问题内容: 我的代码基于@zzzeeek对这个问题的回答。我对其进行了扩展,因此考虑了PostgreSQL的NULL和ARRAY。 一切工作正常,直到结果证明我无法在此VALUES子句中插入带有“%”符号的值-它们插入到结果语句中,这似乎导致绑定问题 我想如果不是我们使用的话,我们可以避免这样的错误。但是下面的所有内容都应该返回纯文本,对吗?我如何修改它以获得基于参数的查询? 问题答案: 我知道了
问题内容: 我正在使用JAXB和xjc将XML Schema编译为Java类。我不想手动编辑此生成的类。我有这样的xml模式: xjc生成仅包含对象列表的类。是否有机会省略该类并直接在该类中具有对象列表? 我知道可以通过注释来完成,但是我不知道如何告诉xjc创建此类注释。 感谢您的任何建议! 最好的问候,马库斯 问题答案: Bjarne Hansen为xjc开发了一个插件,可以解决此问题。不幸的是
问题内容: 我发现了许多类似的问题,但都没有解决我的问题。我的问题是可以访问的功能 我的spring-security.xml代码如下。 当我添加 我的代码时显示找不到资源错误,并且当我删除我的代码时成功执行但可以访问函数 我的控制器功能是。 问题答案: 你应该有 如果您希望注释起作用。 回答评论: 看来您缺少依赖性。 如果您正在使用Maven,则需要: 如果没有,你可以从这里拿到罐子。
如果我更改了方法的名称,它会进行编译,但它不会重写toString,因此print方法不会打印预期的内容。 这是试图定义一个日志子系统,该子系统仅在需要时(当它真的要打印时)对lambda求值,但与非lambda参数兼容。我知道其他的方法来实现它,但我想知道为什么我不能这样做,如果有一个变通办法或我做错了什么,
问题是我写了简单的注释处理器,它根本不处理类型注释。simple annotations processor的源代码如下所示: 有什么想法如何使用或如何通过SimpleAnnotationsProcessor访问类型注释吗?使用可插入的注释处理API对我来说是不必要的,我认为它会比Java反射有更好的性能。无论如何,我也不知道如何通过Java反射访问类型注释。