es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Añadir httpSecurity.csrf().disable() a la configuración de seguridad de Spring permite realizar llamadas a puntos finales sin autenticación.

Tengo la siguiente configuración de seguridad para mi proyecto springboot:

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/testurl1");
}

@Override
public void configure(HttpSecurity httpSecurity) throws Exception {

    httpSecurity.csrf().disable()
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .logout()
            .invalidateHttpSession(true)
            .clearAuthentication(true)
            .logoutSuccessUrl("/")
            .and()
            .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}

Ahora tengo otro endpoint /testurl2. Al llamarlo, un usuario no autorizado debería ser redirigido a una página de error. Si elimino csrf().disable(), funciona bien y la solicitud va a la página /error por defecto. Pero al agregar csrf().disable(), estoy notando un comportamiento muy inusual. Una vez que se llama a otro endpoint, por ejemplo, /testurl3, con un encabezado jwt para autorización, a partir de ese momento el endpoint (/testurl2) se bloquea incluso para un usuario no autorizado, es decir, en lugar de ir a la página de error, llama al endpoint. Aún soy nuevo en Spring Security y Spring, y no estoy seguro de estar escribiendo alguna configuración de forma incorrecta. Por favor, ayúdeme con el problema.

Tags:  ,

Answer

  1. Avatar for davy.ai

    El problema aquí está relacionado con la protección Cross-Site Request Forgery (CSRF) que se desactiva con csrf().disable(). Cuando la protección CSRF está habilitada, Spring Security genera e incluye un token CSRF en cada formulario y solicitud AJAX. Luego se valida este token en el servidor para evitar ataques Cross-Site Request Forgery.

    Al desactivar la protección CSRF, la aplicación se vuelve vulnerable a dichos ataques y cualquier usuario puede hacer solicitudes a cualquier punto final sin un token CSRF.

    En cuanto al comportamiento inusual que está experimentando, podría estar relacionado con el hecho de que el token CSRF se almacena en la sesión del usuario. Dado que está invalidando la sesión en el proceso de cierre de sesión, esto podría estar afectando el comportamiento esperado de la protección CSRF.

    Para solucionar el problema, debe habilitar la protección CSRF e incluir el token de seguridad en sus solicitudes. Puede hacerlo agregando la configuración csrf() a su archivo de configuración de seguridad de la siguiente manera:

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf()
            .ignoringAntMatchers("/test_url_1")
            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            .and()
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .logout()
            .invalidateHttpSession(true)
            .clearAuthentication(true)
            .logoutSuccessUrl("/")
            .and()
            .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }
    

    En esta configuración, estamos indicando a Spring Security que genere un token CSRF y lo almacene en una cookie (con withHttpOnlyFalse()). Luego, estamos configurando el sistema para que ignore el punto final /test_url_1 en la protección CSRF.

    Para incluir el token CSRF en sus solicitudes, debe agregar un campo oculto con el nombre _csrf y el valor del token en cada formulario o solicitud AJAX. Aquí hay un ejemplo de cómo hacer esto en una plantilla Thymeleaf:

    <form th:object="${user}" method="post">
        <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
        <!-- Otros campos del formulario -->
        <button type="submit">Enviar</button>
    </form>
    

    Alternativamente, puede incluir el token CSRF en las cabeceras HTTP de las solicitudes AJAX utilizando JavaScript:

    function getCsrfToken() {
        return document.querySelector('meta[name="_csrf"]').getAttribute('content');
    }
    
    $.ajax({
        url: '/test_endpoint',
        type: 'POST',
        headers: {
            'X-CSRF-TOKEN': getCsrfToken()
        },
        data: {/* Sus datos aquí */}
    }).done(function(response) {
        console.log(response);
    }).fail(function(xhr, status, message) {
        console.error(message);
    });
    

    Recuerde incluir la etiqueta <meta> para el token CSRF en sus plantillas HTML:

    <meta th:name="_csrf" th:content="${_csrf.token}">
    

    Siguiendo estos pasos, debería poder asegurar su aplicación contra ataques CSRF y tener un comportamiento adecuado cuando los usuarios no autorizados intenten acceder a puntos finales protegidos.

Comments are closed.