我遇到以下情况:我的应用程序的授权机制是使用Spring安全性实现的。中央类实现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_GRANTED,ACCESS_ABSTAIN或ACCESS_DENIED)。最好的方法是什么?谢谢。 最佳答案 好吧,在这种情况下,AccesssDecisionVoter接口实际上返回了int。当然,内置的投票器实现总是只返回您提到的三个常量之一(这些是标准访问决策管理器要检查的常量),但是它们实际上没有其他要返回的内容-RoleVoter且仅当主体不具有必需角色时,实例才会拒绝访问。由于您同时使用了投票者和访问决策管理器的实现,因此我看到了几个可用的选项:返回其他整数值作为某种形式的错误代码;将ACCESS_GRANTED,ACCESS_ABSTAIN和ACCESS_DENIED视为其典型值,但将任何其他整数视为带有错误代码的“拒绝访问”。理想情况下,具有可用的错误代码查找表-本质上是穷人的枚举。在您的选民中,照常返回ACCESS_DENIED,并设置一个可公开访问的属性(在选民对象本身或某些静态可访问字段上),并带有错误原因。在您的经理中,如果您的自定义投票者拒绝访问,请检查该属性以获取详细信息。如上所述,在选民中设置错误属性;但请确保传入的Authentication实例是您自己的自定义子类之一,该子类可以提供良好的设置/获取此信息的位置。从选民本身中抛出AccessDeniedException(或合适的子类)。这不是理想的,因为它以访问决策管理器中的逻辑为前提。但是您可以让气泡直接上升,或者在需要时在管理器中将其捕获(自定义子类肯定对此很有用),然后在访问被拒绝时重新抛出(类似于ProviderManager类对变量)。这些都不是显而易见的正确而优雅的答案,但是您应该能够从最合适的那个中获得可行的东西。由于投票者框架内没有出于交流原因的明确支持(从根本上说,这是直接的布尔响应),我认为您无法做得更好。关于java - 如何从使用选民的AccessDecisionManager中引发信息性异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/510846/
10-09 05:29