i have a method secured with spring security as follows:
@PreAuthorize(\"hasRole(\'add_user\')\")
public void addUser(User user) ;
and if a
I have run into the same problem myself and posted another question relating to the same issue. After several hours of digging around, I finally found the solution for my issue. I know this question is 2+ years old, but thought I would update it with information in case it was of value to someone else.
In a nutshell, I noticed that the SimpleMappingExceptionResolver
was handling the exception and resolving it with a default mapping. Consequently, there was no exception left to bubble up the stack to the ExceptionTranslationFilter
which would redirect to the access-denied-handler
.
Please see Spring Security ignoring access-denied-handler with Method Level Security for further information.
According to the spring Security documentation the user of the access-denied-page attribute of the element has been deprecated in Spring 3.0 and above.
We do the following in our app:
AccessDeniedHandlerImpl
. setErrorPage
method, passing in the name of the controller that will display your access denied pageCall super.handle(_request, _response, _exception);
at the end of the handler. Spring will forward control to the controller listed in #2 above.
public class AccessDeniedHandlerApp extends AccessDeniedHandlerImpl {
private static Logger logger = Logger.getLogger(AccessDeniedHandlerApp.class);
private static final String LOG_TEMPLATE = "AccessDeniedHandlerApp: User attempted to access a resource for which they do not have permission. User %s attempted to access %s";
@Override
public void handle(HttpServletRequest _request, HttpServletResponse _response, AccessDeniedException _exception) throws IOException, ServletException {
setErrorPage("/securityAccessDenied"); // this is a standard Spring MVC Controller
// any time a user tries to access a part of the application that they do not have rights to lock their account
<custom code to lock the account>
super.handle(_request, _response, _exception);
}
}
Here's my XML: AccessDeniedHandlerApp
extends 'AccessDeniedHandlerImpl`
<http auto-config='true'>
<intercept-url pattern="/views/**" access="ROLE_USER" />
<form-login login-page="/Login.jsp" authentication-success-handler-ref="loginSuccessFilter"
authentication-failure-handler-ref="loginFailureFilter" />
<logout logout-success-url="/home" />
<access-denied-handler ref="customAccessDeniedHandler"/>
</http>
<beans:bean id="customAccessDeniedHandler" class="org.demo.security.AccessDeniedHandlerApp"/>
Here's my Access Denied Controller - I should have posted this earlier - sorry about that. In order to get the access denied page to come up I had to use a redirect:
@Controller
public class AccessDeniedController {
private static Logger logger = Logger.getLogger(AccessDeniedController.class);
@RequestMapping(value = "/securityAccessDenied")
public String processAccessDeniedException(){
logger.info("Access Denied Handler");
return "redirect:/securityAccessDeniedView";
}
@RequestMapping(value = "/securityAccessDeniedView")
public String displayAccessDeniedView(){
logger.info("Access Denied View");
return "/SecurityAccessDenied";
}
Please let me know if this doesn't resolve it and I'll keep digging - I just tested it again locally here and this should do the trick. }
Spring Security redirect to the access denied page just when the user don't have authorization to access the resource. This is, when the user is authenticated but doesn't have the allowed roles.
But when the problem is not authorization, but authentication, Spring Security redirects to the login page (to let the user authenticate himself/herself), not to the access denied page.
As you have a rule checking for "isAuthenticated()" in the rules, you won't be redirected to the access denied page, but to the login page.
Hope it helps.