Handling AccessDenied with Method Level Security

前端 未结 3 415
春和景丽
春和景丽 2021-01-05 03:29

i have a method secured with spring security as follows:

@PreAuthorize(\"hasRole(\'add_user\')\")
public void addUser(User user) ;

and if a

相关标签:
3条回答
  • 2021-01-05 03:55

    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.

    0 讨论(0)
  • 2021-01-05 03:58

    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:

    1. Create a custom access denied handler by extending the Spring Security framework's AccessDeniedHandlerImpl.
    2. Call the setErrorPage method, passing in the name of the controller that will display your access denied page
    3. In our case we lock the user's account in the custom handler - there's no good reason for any user to ever get an access denied exception unless they're doing something that they should't. We also log what they were trying to access, etc.
    4. Call 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. }

    0 讨论(0)
  • 2021-01-05 04:06

    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.

    0 讨论(0)
提交回复
热议问题