gpt4 book ai didi

java - 如何从使用选民的 AccessDecisionManager 中抛出信息性异常

转载 作者:行者123 更新时间:2023-11-30 06:00:45 27 4
gpt4 key购买 nike

我有以下情况:我的应用程序的授权机制是使用 Spring security 实现的。中央类实现了 AccessDecisionManager 并使用选民(每个选民都实现了 AccessDecisionVoter)来决定是否授予对某些方法的访问权限。计算选票的算法是自定义的:

public class PermissionManagerImpl extends AbstractAccessDecisionManager {

public void decide(
Authentication authentication,
Object object,
ConfigAttributeDefinition config) throws AccessDeniedException {
Iterator<?> iter = getDecisionVoters().iterator();
boolean wasDenied = false;

while (iter.hasNext()) {
AccessDecisionVoter voter = (AccessDecisionVoter) iter.next();
int result = voter.vote(authentication, object, config);

switch (result) {
// Some tallying calculations
}
}

if (wasDenied) {
throw new AccessDeniedException("Access is denied");
}
}

}

在拒绝访问某些方法时,应用程序的客户端有兴趣获得一个信息异常,该异常详细说明访问被拒绝的原因。这意味着将一些信息从选民传递给决策经理。不幸的是,标准 AccessDecisionVoter 传递回决策管理器的唯一信息是可能的返回值之一(ACCESS_GRANTEDACCESS_ABSTAIN ACCESS_DENIED)。

最好的方法是什么?

谢谢。

最佳答案

嗯,在这种情况下,AccesssDecisionVoter 接口(interface)实际上返回一个 int。诚然,内置投票器实现总是只返回您提到的三个常量之一(这些是标准访问决策管理器检查的内容),但是它们实际上没有任何额外的返回 - RoleVoter 例如,当且仅当委托(delegate)人不具有所需角色时,才会拒绝访问。

由于您正在使用自己的选民和访问决策管理器实现,因此我认为您有多种选择:

  1. 返回其他整数值作为某种形式的错误代码;将 ACCESS_GRANTEDACCESS_ABSTAINACCESS_DENIED 视为它们的典型值,但将任何其他整数视为带有错误代码的“拒绝访问”。理想情况下,有一个可用的错误代码查找表 - 本质上是一个穷人的枚举。
  2. 在您的选民中,像往常一样返回 ACCESS_DENIED,并设置一些可公开访问的属性(在选民对象本身或一些静态可访问的字段上)和错误原因。在您的经理中,如果您的自定义选民拒绝访问,请检查属性以获取详细信息。
  3. 同上,在voter中设置一个error属性;但要确保传入的 Authentication 实例是您自己的自定义子类之一,它提供了良好的设置/检索此信息的位置。
  4. 从您的选民内部抛出一个AccessDeniedException(或合适的子类)。这并不理想,因为它预设了访问决策管理器中的逻辑;但是你可以让这个气泡直接上升,或者如果需要的话在管理器中捕获它(自定义子类肯定对此有好处)并在访问确实被拒绝时重新抛出(类似于 ProviderManager类使用它的 lastException 变量。

这些都不是明显正确和优雅的答案,但您应该能够从最合适的答案中得到一些可行的东西。由于出于沟通原因,选民框架内没有明确支持(从根本上说这是一个直接的 boolean 响应),我认为您不能做得更好。

关于java - 如何从使用选民的 AccessDecisionManager 中抛出信息性异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/510846/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com