Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Finalização do carrinho não funciona.

Na aula 8 temos o teste do envio do e-mail. Porém não consigo finalizar meu carrinho. De alguma forma o Spring está traduzindo ${s:mvcUrl('PC#finalizar').build()} para /WEB-INF/views/itens.jsp/pagamentos/finalizar. Com isso minha requisição não entra na finalização do carrinho.

Alterei a jsp para enviar a requisição diretamente para "pagamentos/finalizar".

Nesse momento tomei outro erro do navegador:

HTTP Status 403 – Forbidden
Type Status Report

Message Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.

Description The server understood the request but refuses to authorize it.

Apache Tomcat/8.5.31

Preciso de ajuda com os dois pontos, alguém poderia me ajudar?

3 respostas

O primeiro ponto foi porque depois de colocar o SpringSecurity na aula 4, o modelAndView de CarrinhoComprasController.java estava começando com "/". Ao tirar funcionou.

@RequestMapping(method=RequestMethod.GET)
    public ModelAndView itens() {
        return new ModelAndView("carrinho/itens");
    }

Após isso deu o segundo erro de CSRF token. Adicionei em SecurityConfiguration.java a linha "http.csrf().disable();". Mas não encontrei em que ponto do código do curso está a configuração para passar por esse problema.

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.authorizeRequests()
            .antMatchers("/produtos/form").hasRole("ADMIN")
            .antMatchers("/produtos").hasRole("ADMIN")
            .antMatchers("/carrinho/**").permitAll()
            .antMatchers("/produtos/**").permitAll()
            .antMatchers("/pagamento/**").permitAll()    
            .antMatchers("/").permitAll()
            .anyRequest().authenticated()
            .and().formLogin().loginPage("/login")
                .defaultSuccessUrl("/produtos").permitAll()
            .and().logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                    .permitAll().logoutSuccessUrl("/login");
    }

Alguém poderia me ajudar a entender em que ponto está essa alteração?

solução!

Fala matcastro, tudo bem ?

Bom que já conseguiu pegar a causa do primeiro problema.

Quando a questão do problema com a proteção contra CSRF, dê uma olhada nessa task do curso -> https://cursos.alura.com.br/course/springmvc-2-integracao-cache-seguranca-e-templates/task/12249

Nessa tarefa é explicada a ideia dos ataques conhecidos como CSRF (Cross Site Request Forgery). Aqueles ataques onde requisições maliciosas são feitas para nosso servidor enviando nosso id de sessão tentando se passar por um usuário real do sistema. Muito comum de ser feito através de formulários fake adicionados em paginas da nossa aplicação.

O Spring Security quando ativado na nossa aplicação ja ativa um recurso padrão que é a proteção contra esses ataques. Essa proteção se baseia em esperar um token csrf valido vindo em cada requisição do tipo post. Ou seja, todo form da nossa app, precisa enviar além dos dados normais, mais esse token, para o spring security validar. (Por isso que estava dando o erro inicialmente, como o token não estava presente, ele recusava a requisição, respondendo um 403 Forbidden).

Com o código que você adicionou: http.csrf().disable(); você está desativando na configuração programática esse recurso de proteção (o que não é recomendado). Deveríamos contar com a proteção.

É bem fácil cumprir o que ele nos obriga nas nossas requisições do tipo post e nos mantermos protegidos. Basta adicionar em cada formulário um input adicional que enviará o token: <input type="hidden" name="${_csrf.parameterName }" value="${_csrf.token }" />. Perceba que ambos os valores de name e value já são gerados dinamicamente pelo próprio Spring Security e disponibilizados via expression language.

Com esse token sendo enviado em cada post o problema será resolvido.

Espero ter ajudado. Abraço!

Obrigado Rafael! Ajudou bastante. Não só dando a resposta, mas me ajudando a entender realmente o ponto.