11
respostas

Erro 400 bad request

Olá estou tendo o mesmo problema que alguns alunos relataram aqui, erro 400 na chamada do /auth, alguém sabe o que pode ser ? Até 5 minutos atrás tudo estava funcionando, der repente parou.

11 respostas

Oi Alexandre,

Posta aqui como você disparou a requisção no postman e as suas classes controller, dto e securityConfigurations.

Olá, segue a SecurityConfigurations

package br.com.framework.api.frameworkapi.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import br.com.framework.api.frameworkapi.repository.UserRepository;

@EnableWebSecurity
@Configuration
public class SecurityConfigurations extends WebSecurityConfigurerAdapter {

    @Autowired
    private ServiceAuthentication serviceAuthentication;

    @Autowired
    private TokenService tokenService;

    @Autowired
    UserRepository userRepository;

    @Override
    @Bean
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    // Authentication Settings
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(serviceAuthentication).passwordEncoder(new BCryptPasswordEncoder());
    }

    // Authorization settings
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
        .antMatchers(HttpMethod.POST, "/auth").permitAll()
        .anyRequest()                
        .authenticated()
        .and().csrf().disable()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and().addFilterBefore(new AuthenticatorTokenFilter(tokenService, userRepository), UsernamePasswordAuthenticationFilter.class);
        }

    // Static resource settings (js, css, images)
    @Override
    public void configure(WebSecurity web) throws Exception {

    }

    /*public static void main(String[] args) {
        String senha = new BCryptPasswordEncoder().encode("12345");
        System.out.println(senha);
    }*/

}

Segue o AuthController

package br.com.framework.api.frameworkapi.controller;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import br.com.framework.api.frameworkapi.dto.TokenDto;
import br.com.framework.api.frameworkapi.form.AuthForm;
import br.com.framework.api.frameworkapi.security.TokenService;

@RestController
@CrossOrigin(origins = "http://localhost:4200", maxAge = 3600)
@RequestMapping("/auth")
public class AuthController {

    @Autowired
    private AuthenticationManager authManager;

    @Autowired
    private TokenService tokenService;

    @PostMapping
    public ResponseEntity<TokenDto> authetic(@RequestBody @Valid AuthForm form){
        UsernamePasswordAuthenticationToken data = form.convert();

        try {
            Authentication authentication = authManager.authenticate(data);
            String token = tokenService.generateToken(authentication);
            return ResponseEntity.ok(new TokenDto(token, "Bearer"));
        } catch (org.springframework.security.core.AuthenticationException e) {
            System.out.println("dando ruim aqui");
            return ResponseEntity.badRequest().build();
        }

    }

}

TokenDto

package br.com.framework.api.frameworkapi.dto;

public class TokenDto {

    private String token;
    private String type;

    public TokenDto(String token, String type) {
        this.token = token;
        this.type = type;

    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

}

TokenService

package br.com.framework.api.frameworkapi.security;

import java.util.Date;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import br.com.framework.api.frameworkapi.model.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

@Service
public class TokenService {

    @Value("${framework-api.jwt.expiration}")
    private String expiration;

    @Value("${framework-api.jwt.secret}")
    private String secret;

    public String generateToken(Authentication authentication) {
        User logged = (User) authentication.getPrincipal();
        Date now = new Date();
        Date dateExpiration = new Date(now.getTime() + Long.parseLong(expiration));
        return Jwts.builder().setIssuer("Framework API").setSubject(logged.getId().toString()).setIssuedAt(now)
                .setExpiration(dateExpiration).signWith(SignatureAlgorithm.HS256, secret).compact();
    }

    public boolean isValidToken(String token) {
        try {
            Jwts.parser().setSigningKey(this.secret).parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public Long getIdUser(String token) {
        Claims claims = Jwts.parser().setSigningKey(this.secret).parseClaimsJws(token).getBody();
        return Long.parseLong(claims.getSubject());
    }

}

AuthenticatorTokenFilter

package br.com.framework.api.frameworkapi.security;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import br.com.framework.api.frameworkapi.model.User;
import br.com.framework.api.frameworkapi.repository.UserRepository;

public class AuthenticatorTokenFilter extends OncePerRequestFilter {

    private TokenService tokenService;
    private UserRepository userRepository;

    public AuthenticatorTokenFilter(TokenService tokenService, UserRepository userRepository) {
        this.tokenService = tokenService;
        this.userRepository = userRepository;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        String token = recoverToken(request);
        boolean valid = tokenService.isValidToken(token);
        if (valid) {
            authenticationClient(token);
        }

        filterChain.doFilter(request, response);

    }

    private void authenticationClient(String token) {
        Long idUser = tokenService.getIdUser(token);
        User user = userRepository.findById(idUser).get();
        UsernamePasswordAuthenticationToken authentication = 
                new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);

    }

    private String recoverToken(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (token == null || token.isEmpty() || !token.startsWith("Bearer ")) {
            return null;
        }
        return token.substring(7, token.length());
    }

}

ServiceAuthentication

package br.com.framework.api.frameworkapi.security;

import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import br.com.framework.api.frameworkapi.model.User;
import br.com.framework.api.frameworkapi.repository.UserRepository;

@Service
public class ServiceAuthentication implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Optional<User> user = userRepository.findByUsername(username);
        if (user.isPresent()) {
            return user.get();
        }

        throw new UsernameNotFoundException("Dados inválidos");
    }

}

Segue como fiz a requisição no postman Insira aqui a descrição dessa imagem para ajudar na acessibilidade Insira aqui a descrição dessa imagem para ajudar na acessibilidade Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Segue o retorno que aparece no console do eclipse

Hibernate: 
    select
        user0_.id as id1_7_,
        user0_.pwd as pwd2_7_,
        user0_.username as username3_7_ 
    from
        users user0_ 
    where
        user0_.username=?
dando ruim aqui

A principio nada de problemas nos códigos que você mandou. E a requsição está chegando normalmente, pois o select foi efetuado.

Coloca essa linha no seu catch, do AuthController:

} catch (org.springframework.security.core.AuthenticationException e) {
    e.printStackTrace();

    System.out.println("dando ruim aqui");
    return ResponseEntity.badRequest().build();
}

E posta aqui a exception que vai sair no console.

Segue o resultado, ficou mais simples o entendimento agora, faltou um construtor padrão na entity User, eu havia criado apenas com os campos necessários


org.springframework.security.authentication.InternalAuthenticationServiceException: No default constructor for entity:  : br.com.framework.api.frameworkapi.model.User; nested exception is org.hibernate.InstantiationException: No default constructor for entity:  : br.com.framework.api.frameworkapi.model.User

Correção

public User () {

    }