bwright
bwright

Reputation: 936

Custom AccessDeniedHandler not called

I have implemented a custom AccessDeniedHandler:

public class MyAccessDeniedHandler implements AccessDeniedHandler {


    @Override
    public void handle(HttpServletRequest request,
        HttpServletResponse response,
        AccessDeniedException accessDeniedException) throws IOException,
        ServletException {

        System.err.println("Access DENIED ");
        response.sendRedirect("/public/error.xhtml");

    }
}

And configured it in WebSecurityConfigurerAdapter:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/docs/**", "/public/**", "/javax.faces.resource/**", "/index.html", "/uploads/**").permitAll()
            .anyRequest().authenticated()
        .and()
            .formLogin()
            .loginPage("/public/login.xhtml")
            .failureUrl("/public/login.xhtml?l=error")
            .defaultSuccessUrl("/public/login.xhtml?l=success")
            .permitAll()
        .and()
            .logout()
            .permitAll()
            .deleteCookies()
            .logoutSuccessUrl("/public/login.xhtml?faces-redirect=true&l=logout")
            .invalidateHttpSession(true)
        .and()
            .exceptionHandling()
            .accessDeniedHandler(new MyAccessDeniedHandler())
        .and()
            .csrf()
            .disable();
}

I am using @PostAuthorize with a custom PermissionEvaluator

The PermissionEvaluator is working, but the AccessDeniedHandler is never called. Instead I am only getting the stacktrace of the Access Denied exception.

thanks for the Help.

EDIT: Added Stacktrace

javax.el.ELException: /secured/organisation/ou.xhtml @17,67 value="#{ouBean.activeOU.name}": org.springframework.security.access.AccessDeniedException: Access is denied
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UICommand.getValue(UICommand.java:218)
at org.primefaces.component.menu.BaseMenuRenderer.encodeMenuItemContent(BaseMenuRenderer.java:249)
at org.primefaces.component.menu.BaseMenuRenderer.encodeMenuItem(BaseMenuRenderer.java:215)
at org.primefaces.component.breadcrumb.BreadCrumbRenderer.encodeMarkup(BreadCrumbRenderer.java:75)
at org.primefaces.component.menu.BaseMenuRenderer.encodeEnd(BaseMenuRenderer.java:113)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:919)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1863)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:176)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:889)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:456)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:133)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at org.ocpsoft.rewrite.faces.RewriteViewHandler.renderView(RewriteViewHandler.java:186)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:178)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.ocpsoft.rewrite.servlet.RewriteFilter.doFilter(RewriteFilter.java:205)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:168)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.el.ELException: org.springframework.security.access.AccessDeniedException: Access is denied
at javax.el.BeanELResolver.getValue(BeanELResolver.java:368)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstValue.getValue(AstValue.java:140)
at com.sun.el.parser.AstValue.getValue(AstValue.java:204)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:226)
at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
... 96 more
Caused by: org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.expression.method.ExpressionBasedPostInvocationAdvice.after(ExpressionBasedPostInvocationAdvice.java:62)
at org.springframework.security.access.prepost.PostInvocationAdviceProvider.decide(PostInvocationAdviceProvider.java:41)
at org.springframework.security.access.intercept.AfterInvocationProviderManager.decide(AfterInvocationProviderManager.java:81)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.afterInvocation(AbstractSecurityInterceptor.java:316)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:73)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
at de.uni_freiburg.brainlinks_braintools.rais.service.OrganisationalUnitService$$EnhancerBySpringCGLIB$$c32d2659.getById(<generated>)
at de.uni_freiburg.brainlinks_braintools.rais.model.OrganisationalUnit.getById(OrganisationalUnit.java:218)
at de.uni_freiburg.brainlinks_braintools.rais.managedBeans.OrganisationalUnitBean.getActiveOU(OrganisationalUnitBean.java:168)
at sun.reflect.GeneratedMethodAccessor320.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:363)
... 103 more

Upvotes: 5

Views: 7411

Answers (5)

Jan Tom&#225;šek
Jan Tom&#225;šek

Reputation: 175

In my case the problem was that in addition to my CustomAccessDeniedHandler there was also a global resource exception handler with @ControllerAdvice. I solved this by rethrowing the exception in the global handler (as advised here https://github.com/spring-projects/spring-security/issues/6908), then my CustomAccessDeniedHandler gets executed.

@ControllerAdvice
public class ResourceExceptionHandler {
...
    @ExceptionHandler(AccessDeniedException.class)
    public ResponseEntity accessDeniedException(AccessDeniedException e) throws AccessDeniedException {
        log.info(e.toString());
        throw e;
    }
...
}

Upvotes: 2

emilpmp
emilpmp

Reputation: 1736

I faced the same issue. My custom AccessDeniedHandler was not being triggered. So I marked the AuthenticationEntryPoint class as @ControllerAdvice and added a new function with the annotation @ExceptionHandler . This is working for me now. You can see the complete code here

Upvotes: 0

bwright
bwright

Reputation: 936

Ok It seems to be working when I change

servletContext.setInitParameter("javax.faces.PROJECT_STAGE",
            "Development");

To

servletContext.setInitParameter("javax.faces.PROJECT_STAGE",
            "Production");

Anyone may elaborate on why this is the behaviour? I would expect the 403 error page to be displayed and the stack trace in the log.

Upvotes: 2

Mudassar
Mudassar

Reputation: 3215

1.You might want to set error page like this in your AccessDeniedHandler

 public void setErrorPage(String errorPage) {
      ....
    }

Because the exception is valid but it is unable to find the page hence setting here might help

2. If everything fails you can also you can try this approach where in you can use the url pattern

.exceptionHandling().accessDeniedPage("/accessDeniedPage.htm")

Error page will always start with "/"

@Controller
public class MyAccessDeniedHandler {

    @RequestMapping(value = "/accessDeniedPage.htm", method = RequestMethod.GET)
    public String redirectAccessDenied(Model model) throws IOException, ServletException {
        System.out.println(" Redirect Access Denied Handler!");
        return "myerrorpage";
    }
}

3. In addition to above you can still use the custom AccessDeniedHandler by simply map it via a bean config

.exceptionHandling().accessDeniedPage("/accessDeniedPage.htm")
 @Bean( name = "/accessDeniedPage.htm" )
    public AccessDeniedHandler  authenticationEntryPoint() {    
        return new MyAccessDeniedHandler();
    }

or

.accessDeniedHandler( this.acessDeniedHandler() );
 @Bean( name = "/accessDeniedPage.htm" )
        public AccessDeniedHandler  accessDeniedHandler() {    
            return new MyAccessDeniedHandler();
        }

public class MyAccessDeniedHandler implements AccessDeniedHandler {    

    @Override
    public void handle(HttpServletRequest request,
        HttpServletResponse response,
        AccessDeniedException accessDeniedException) throws IOException,
        ServletException {

        System.err.println("Access DENIED ");
        response.sendRedirect("/public/error.xhtml");

    }
}

Upvotes: 0

prsmax
prsmax

Reputation: 223

WebSecurityConfigurerAdapter

.and()
.exceptionHandling()
.accessDeniedHandler(new AccessDeniedHandler())

i think you need to pick your own MyAccessDeniedHandler() here

Upvotes: 0

Related Questions