Mostrando postagens com marcador Spring Security. Mostrar todas as postagens
Mostrando postagens com marcador Spring Security. Mostrar todas as postagens

terça-feira, 11 de novembro de 2025

Configurando CSRF (Cross-Site Request Forgery) - Spring Security

        Nesse post vou falar sobre CSRF (Cross-Site Request Forgery - Falsificação de solicitação entre sites). O CSRF é um tipo de ataque onde um site malicioso tenta forçar o navegador de um usuário autenticado a enviar uma requisição indesejada para outro site (por exemplo, seu sistema), usando os cookies de sessão válidos daquele usuário.

        O Spring Security, por padrão, habilita a proteção contra CSRF para evitar isso — especialmente em aplicações web com sessões e formulários HTML (POST). Podemos desativar caso iremos usar aplicações com tokens JWT ou usar a configuração padrão. Abaixo temos os 2 exemplos para o Spring Boot a partir da versão 3.0: 


1. Desativando o CSRF (uso em APIs REST, JWT, stateless)

Esse é o que você mostrou:

httpSecurity
    .csrf(csrf -> csrf.disable())
    .authorizeHttpRequests(auth -> auth
        .requestMatchers("/api/**").permitAll()
        .anyRequest().authenticated()
    );
  • A aplicação não mantém sessão (SessionCreationPolicy.STATELESS costuma acompanhar isso).

  • Ideal para APIs REST com tokens JWT, pois o ataque CSRF depende de cookies, e aqui normalmente não há cookies.

Exemplo completo:

@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .csrf(csrf -> csrf.disable())
        .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/auth/**").permitAll()
            .anyRequest().authenticated()
        )
        .httpBasic(withDefaults());
    return http.build();
}


2. Mantendo o CSRF Ativado (uso em apps web com formulários HTML)

        Aqui o CSRF é mantido ativo, e o Spring vai automaticamente gerar e validar tokens CSRF em formulários HTML.

httpSecurity
    .csrf(withDefaults()) // mantém o CSRF habilitado
    .authorizeHttpRequests(auth -> auth
        .requestMatchers("/login", "/register", "/css/**", "/js/**").permitAll()
        .anyRequest().authenticated()
    )
    .formLogin(withDefaults()) // usa login por formulário
    .logout(withDefaults());

        Nesse caso:

  • Todo formulário POST precisa incluir um campo hidden com o token CSRF.

  • O Spring automaticamente injeta esse token se você usar o Thymeleaf ou Spring Form Taglib, por exemplo:

    <form th:action="@{/login}" method="post">
        <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
        <!-- campos de login -->
    </form>
    


sexta-feira, 17 de julho de 2020

Resolvendo problema CORS no Spring

Olá, hoje vou falar sobre o CORS – Cross-Origin Resource Sharing que significa compartilhamento de recursos de origem cruzada.

Antes era muito comum o uso de iFrames ou similares para fazer com que um site acessasse diretamente conteúdo de outros o que também era válido para aplicações web mais complexas, o problema é que isso começou a ser explorado por pessoas mal intencionadas para se passarem por um site ou serviço que não são e roubar informações ou outras atividades ilícitas. Então os navegadores começaram a “bloquear” esse tipo de coisa, validando antes se a origem tem acesso ao backend vindo de um IP diferente ou não configurado em uma digamos “White list”.

         Tratar o CORS é obrigação do backend, e vamos ver como fazer isso no Spring. No caso, podemos fazer de duas formas: liberando geral ou especificando as URLs que terão o acesso garantido.

    Para liberar qualquer endereço, podemos desabilitar o CORS na classe de configuração de segurança:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/v2/api-docs",
                "/configuration/ui",
                "/swagger-resources/**",
                "/configuration/security",
                "/swagger-ui.html",
                "/webjars/**");
    }

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

        http.authorizeRequests().antMatchers("/xxx/**").authenticated();
        http.authorizeRequests().anyRequest().permitAll();
        http.cors().disable();

    }

}


        Ou podemos criar um bean na classe principal da aplicação e passar o padrão de URL como "/**":
       
@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**").allowedOrigins("http://localhost:9000");
        }
    };
}


    Para liberar endereços específicos, o que é mais recomendado, basta passar o endereço no lugar do "/**":

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/greeting-javaconfig").allowedOrigins("http://localhost:9000");
        }
    };
}


     Outra forma de fazer é ao invés de criar o bean na classe principal, é criar uma classe específica com a configuração, deixando-a mais explícita:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebMvc
public class CorsConfiguration implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }

}


        Exemplo de configuração do CORS em versões mais novas do Spring Boot:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of("http://localhost:3000"));
configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(List.of("*"));
configuration.setAllowCredentials(true);

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}

@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors(cors -> cors.configure(http)) // aplica o CorsConfigurationSource registrado
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/**").permitAll()
.anyRequest().authenticated()
);

return http.build();
}

}

 



 FOnte: https://spring.io/guides/gs/rest-service-cors/ 

quinta-feira, 4 de junho de 2020

Configurando o Spring Security 5 com autenticação em memória

    Do Spring Security 4 para o 5 configurar um usuário e senha em memória não é mais tão simples, porém nesse link abaixo tem a configuração necessária para fazê-lo basicamente como antes:

https://spring.io/guides/gs/securing-web/

    Basicamente o que muda é a classe WebSecurityConfig que passa a retornar um Bean do tipo UserDetailsService ao invés de criarmos o método: 

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("danieloliveira").password("oliveira").roles("USER");
}

    Ficando assim:

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/h2-console/**").permitAll().anyRequest().authenticated().and()
            .httpBasic().and().csrf().disable();
}

@Bean
@Override
public UserDetailsService userDetailsService() {
     UserDetails user = User.withDefaultPasswordEncoder().username("seu_usuario").password("sua_senha")
        .roles("USER").build();

    return new InMemoryUserDetailsManager(user);
}

}