Ok tôi đã tìm thấy cách ngăn chặn AccessDeniedException. Tuy nhiên điều này không giải quyết được vấn đề. Việc truy tố phần còn lại của mã bây giờ contunies normaly, tuy nhiên cuộc gọi phương thức bảo đảm không được ngăn chặn ngay cả khi hasPermission trả về false.
Đây là cách tôi quản lý để ngăn chặn sự AccessDeniedException từ stoping tất cả mọi thứ:
Bạn cần phải thực hiện một AccessDecisionManager nơi bạn ngăn chặn sự AccessDeniedException tuyên truyền. Đó là phần dễ dàng. Tôi trông giống như sau:
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);
}
}
}
Sau đó, phần khó khăn ... thiết lập ngữ cảnh ứng dụng.
<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>
Bất kỳ ý tưởng nào về cách ngăn chặn phương thức được gọi mà không dừng mọi thứ?
Tôi đã làm một điều gì đó khá đơn giản hơn, tôi vừa thêm một lời khuyên về MethodSecurityInterceptor để bắt ngoại lệ với @Around sao cho quá trình truyền qua điểm đó bị ngăn chặn . Bằng cách đó tôi có thể tránh việc cấu hình Spring Security bằng chân, điều này rất phức tạp. Tuy nhiên những gì bạn đề xuất là cách kinh điển để làm điều đó và nó hoạt động. – Chepech
Rất đẹp! Tôi tự hỏi nếu có cách nào chúng ta có thể thay đổi hành vi của beforeInvocation() (sử dụng AOP) để kiểm tra quyền của người dùng trên phương thức cụ thể (OP muốn bảo vệ) và thay thế mi bằng một instance MethodInvocation giả thay vì lo lắng về AccessDeniedException. – Ritesh
@Chepech @Around giải pháp có vẻ rất đơn giản và thanh lịch. Nếu bạn cập nhật mã @Around được đề cập, tôi sẽ sẵn sàng bỏ phiếu. – Ritesh