Хорошо, я нашел способ предотвратить AccessDeniedException. Однако это не решает проблему. Исключение остальной части кода теперь нормализуется, однако вызов защищенного метода не предотвращается, даже если hasPermission возвращает false.
Это, как мне удалось предотвратить AccessDeniedException от останавливая все:
Вам нужно реализовать AccessDecisionManager, где вы предотвратить AccessDeniedException распространения. Это легкая часть. Шахта выглядит так:
public class SkipMethodCallAccessDecisionManager extends AffirmativeBased {
@Override
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes){
try{
super.decide(authentication, object, configAttributes);
}catch(AccessDeniedException adex){
logger.debug("Access Denied on:" + object);
}
}
}
Тогда сложная часть ... настройка контекста приложения.
<sec:global-method-security pre-post-annotations="enabled" access-decision-manager-ref="skipMethodCallAccessDecisionManager "/>
<bean id="skipMethodCallAccessDecisionManager" class="com.application.auth.vote.SkipMethodCallAccessDecisionManager ">
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter">
<constructor-arg ref="expressionBasedPreInvocationAdvice"/>
</bean>
<!-- Insert RoleVoter if required -->
<bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
</list>
</property>
</bean>
<bean id="expressionBasedPreInvocationAdvice" class="org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice">
<property name="expressionHandler" ref="expressionHandler"/>
</bean>
Любые идеи о том, как предотвратить вызов метода без остановки всего?
Я закончил делать что-то более простое, я просто добавил совет по методу MethodSecurityInterceptor, который ловит исключение с помощью @Around, чтобы предотвратить распространение этой точки , Таким образом, я мог бы избежать настройки Spring Security пешком, что очень сложно. Однако то, что вы предлагаете, - это канонический способ сделать это, и он работает. – Chepech
Очень приятно! Интересно, можно ли каким-либо образом изменить поведение beforeInvocation() (используя AOP), чтобы проверить права пользователя на определенный метод (который OP хочет защитить) и заменить mi на фиктивный экземпляр MethodInvocation вместо того, чтобы беспокоиться о AccessDeniedException. – Ritesh
@Chepech @ Практическое решение кажется очень простым и элегантным. Если вы обновите соответствующий код @Around, я с радостью проголосую за него. – Ritesh