Saltar al contenido

Spring Security: creación de una respuesta personalizada de acceso denegado 403

Haz todo lo posible por comprender el código bien antes de usarlo a tu proyecto y si ttienes algo que aportar puedes decirlo en los comentarios.

Solución:

Creo que resolví el problema. En lugar de crear una implementación de AccessDeniedHandler, tuve que crear un AuthenticationEntryPoint personalizado y configurarlo en el manejo de excepciones.

WebConfig ahora se ve así:

@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter 

    private UserDetailsService userDetailsService;
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    public WebSecurity(UserDetailsService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) 
        this.userDetailsService = userDetailsService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                    .csrf().disable()
                    .authorizeRequests()
                    .antMatchers(HttpMethod.POST, REGISTER_URL).permitAll()
                    .anyRequest().authenticated()
                .and()
                    .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
                .and()
                    .addFilter(new JWTAuthenticationFilter(authenticationManager(), tokenProvider()))
                    .addFilter(new JWTAuthorizationFilter(authenticationManager(), tokenProvider()));

    

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
    

    @Bean
    public TokenProvider tokenProvider()
        return new TokenProvider();
    

    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint()
        return new CustomAuthenticationEntryPoint();
    

y CustomAuthenticationEntryPoint:

public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint 

    @Override
    public void commence(HttpServletRequest req, HttpServletResponse res, AuthenticationException authException) throws IOException, ServletException 
        res.setContentType("application/json;charset=UTF-8");
        res.setStatus(403);
        res.getWriter().write(JsonBuilder //my util class for creating json strings
                .put("timestamp", DateGenerator.getDate())
                .put("status", 403)
                .put("message", "Access denied")
                .build());
    

Ahora todo funciona como quería.

Tengo el mismo problema e intenté resolverlo según la respuesta correcta, pero no resuelve el problema. La mejor manera de manejar esto es implementar un controlador de acceso denegado personalizado. La implementación de AuthenticationEntryPoint es mejor para manejar 401, acceso NO AUTORIZADO y la implementación de AccessDeniedHandler está ahí para 403, acceso PROHIBIDO.

Anule el método de AccessDeniedHandler en su clase de implementación como:

@Override
public void handle(HttpServletRequest request, HttpServletResponse response, 
AccessDeniedException accessDeniedException) throws IOException, ServletException 
    response.getWriter().write("Access Denied... Forbidden");

Y agregue este controlador de acceso denegado personalizado en su configuración de seguridad de esta manera:

.exceptionHandling()     
.authenticationEntryPoint(authenticationEntryPoint())
.accessDeniedHandler(accessDeniedHandler())

Prueba esto

 @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.NEVER)
                .and()
                    .csrf().disable()
                    .authorizeRequests()
                    .antMatchers(HttpMethod.POST, REGISTER_URL).permitAll()
                    .anyRequest().authenticated()

                 .and().exceptionHandling().accessDeniedPage("/view/notAuth")
                .and()
                    .addFilter(new JWTAuthenticationFilter(authenticationManager(), tokenProvider()))
                    .addFilter(new JWTAuthorizationFilter(authenticationManager(), tokenProvider()));

    

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
    

    @Bean
    public TokenProvider tokenProvider()
        return new TokenProvider();
    

Y haga esta clase de configuración para ver la página

import java.util.List;

import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;


@Configuration
public class ViewRegistryConfig implements WebMvcConfigurer 

    @Override
    public void addViewControllers(ViewControllerRegistry registry) 
        registry.addViewController("/view/notAuth").setViewName("notAuth");
    

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) 
        // TODO Auto-generated method stub

    

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) 
        // TODO Auto-generated method stub

    

    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) 
        // TODO Auto-generated method stub

    

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) 
        // TODO Auto-generated method stub

    

    @Override
    public void addFormatters(FormatterRegistry registry) 
        // TODO Auto-generated method stub

    

    @Override
    public void addInterceptors(InterceptorRegistry registry) 
        // TODO Auto-generated method stub

    

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) 
        // TODO Auto-generated method stub

    

    @Override
    public void addCorsMappings(CorsRegistry registry) 
        // TODO Auto-generated method stub

    

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) 
        // TODO Auto-generated method stub

    

    @Override
    public void addArgumentResolvers(List argumentResolvers) 
        // TODO Auto-generated method stub

    

    @Override
    public void addReturnValueHandlers(List returnValueHandlers) 
        // TODO Auto-generated method stub

    

    @Override
    public void configureMessageConverters(List> converters) 
        // TODO Auto-generated method stub

    

    @Override
    public void extendMessageConverters(List> converters) 
        // TODO Auto-generated method stub

    

    @Override
    public void configureHandlerExceptionResolvers(List exceptionResolvers) 
        // TODO Auto-generated method stub

    

    @Override
    public void extendHandlerExceptionResolvers(List exceptionResolvers) 
        // TODO Auto-generated method stub

    

    @Override
    public Validator getValidator() 
        // TODO Auto-generated method stub
        return null;
    

    @Override
    public MessageCodesResolver getMessageCodesResolver() 
        // TODO Auto-generated method stub
        return null;
    




Si te gusta la idea, puedes dejar una sección acerca de qué le añadirías a esta noticia.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *