title: Spring Security JWT response 403
body: <p>I'm trying to learn Java and Spring, i've been following a tutorial step by step about spring security, but i'm getting the http response forbidden, again i'm a rookie in Java so if it's a silly mistake, bealive me i can't see it.</p>
  
  <p>here's my SpringSecurityConfig.java</p>
  
  <pre><code>package com.bolsadeideasspringboot.app;
  import javax.sql.DataSource;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
  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.config.http.SessionCreationPolicy;
  import org.springframework.security.core.userdetails.User;
  import org.springframework.security.core.userdetails.User.UserBuilder;
  import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  import org.springframework.security.crypto.factory.PasswordEncoderFactories;
  import org.springframework.security.crypto.password.PasswordEncoder;
  import com.bolsadeideasspringboot.app.auth.filter.JWTAuthenticationFilter;
  import com.bolsadeideasspringboot.app.auth.filter.JWTAuthorizationFilter;
  import com.bolsadeideasspringboot.app.auth.handler.LoginSuccessHandler;
  import com.bolsadeideasspringboot.app.models.service.JpaUserDetailService;
  
  @Configuration
  @EnableWebSecurity
  @EnableGlobalMethodSecurity(securedEnabled = true)
  public class SpringSecurityConfig extends WebSecurityConfigurerAdapter{
  
  @Autowired
  private LoginSuccessHandler successHandler;
  
  @Autowired
  private DataSource dataSource;
  
  @Autowired
  private BCryptPasswordEncoder passwordEncoder;
  
  @Autowired
  private JpaUserDetailService userDetailsService;
  
  @Override
  protected void configure(HttpSecurity http) throws Exception {
  
      http.authorizeRequests()
      .antMatchers("/", "/css/**", "/js/**", "/img/**", "/listar**").permitAll()
      .anyRequest().authenticated()
      .and()
      .addFilter(new JWTAuthenticationFilter(authenticationManager()))
      .addFilter(new JWTAuthorizationFilter(authenticationManager()))
      .csrf().disable()
      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
  }
  
  @Autowired
  public void configurerglobal(AuthenticationManagerBuilder build) throws Exception {
  
  
      build.userDetailsService(userDetailsService)
      .passwordEncoder(passwordEncoder);
  
  }
  
  }
  </code></pre>
  
  <p>Here's my JWTAuthenticationFilter.java</p>
  
  <pre><code>package com.bolsadeideasspringboot.app.auth.filter;
  
  import java.io.Console;
  import java.io.IOException;
  import java.util.Collection;
  import java.util.Date;
  import java.util.HashMap;
  import java.util.Map;
  import javax.servlet.FilterChain;
  import javax.servlet.ServletException;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import org.springframework.security.authentication.AuthenticationManager;
  import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  import org.springframework.security.core.Authentication;
  import org.springframework.security.core.AuthenticationException;
  import org.springframework.security.core.GrantedAuthority;
  import org.springframework.security.core.userdetails.User;
  import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
  
  import com.bolsadeideasspringboot.app.models.entity.Usuario;
  import com.fasterxml.jackson.core.JsonParseException;
  import com.fasterxml.jackson.databind.JsonMappingException;
  import com.fasterxml.jackson.databind.ObjectMapper;
  
  import io.jsonwebtoken.Claims;
  import io.jsonwebtoken.Jwts;
  import io.jsonwebtoken.SignatureAlgorithm;
  
  public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
  
  private AuthenticationManager authManager;
  
  public JWTAuthenticationFilter(AuthenticationManager authManager) {
      this.authManager = authManager;
      setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/api/login", "POST"));
      //setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/api/cliente/listar", "POST"));
  }
  
  @Override
  public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
          throws AuthenticationException {
      // TODO Auto-generated method stub
  
  
      String username = obtainUsername(request);
      String password = obtainPassword(request);
  
      if(username != null &amp;&amp; password != null) {
          System.out.println("");
      }
      else {
          Usuario user = null;
          try {
              user = new ObjectMapper().readValue(request.getInputStream(), Usuario.class);
              username = user.getUsername();
              password = user.getPassword();
  
          } catch (JsonParseException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          } catch (JsonMappingException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          } catch (IOException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
      }
  
      UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username,password);
  
      username = username.trim();
  
      return authManager.authenticate(authToken);
  }
  
  @Override
  protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
          Authentication authResult) throws IOException, ServletException {
      // TODO Auto-generated method stub
  
      Collection&lt;? extends GrantedAuthority&gt; roles = authResult.getAuthorities();
      Claims claims = Jwts.claims();
      claims.put("authorities", new ObjectMapper().writeValueAsString(roles));
  
      String token = Jwts.builder()
              .setClaims(claims)
              .setSubject(authResult.getName())
              .signWith(SignatureAlgorithm.HS512, "Clave!#$%&amp;/()Secreta.//1234.4321.//.abcd.dcba.1a.2b.3c.4d.12345678".getBytes())
              .setIssuedAt(new Date())
              .setExpiration(new Date(System.currentTimeMillis() + 3600000L))
              .compact();
  
      response.addHeader("Authorization", "Bearer"+token);
  
      Map&lt;String, Object&gt; body = new HashMap&lt;String, Object&gt;();
      body.put("token", token);
      body.put("user", (User)authResult.getPrincipal());
      body.put("mensaje", "Inicio de sesión correcto");
  
      response.getWriter().write(new ObjectMapper().writeValueAsString(body));
      response.setStatus(200);
      response.setContentType("application/json");
  
  
      //super.successfulAuthentication(request, response, chain, authResult);
  }
  
  @Override
  protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
          AuthenticationException failed) throws IOException, ServletException {
      // TODO Auto-generated method stub
  
      Map&lt;String, Object&gt; body = new HashMap&lt;String, Object&gt;();
      body.put("mensaje","Error de Autenticación, Claves de Acceso incorrectas");
      body.put("Error", failed.getMessage());
  
      response.getWriter().write(new ObjectMapper().writeValueAsString(body));
      response.setStatus(401);
      response.setContentType("application/json");
  
  }
  }
  </code></pre>
  
  <p>Here's the JWTAuthorizationFilter.java</p>
  
  <pre><code>package com.bolsadeideasspringboot.app.auth.filter;
  
  import java.io.IOException;
  import java.util.Arrays;
  import java.util.Collection;
  import javax.servlet.FilterChain;
  import javax.servlet.ServletException;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  
  import org.springframework.security.authentication.AuthenticationManager;
  import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  import org.springframework.security.core.GrantedAuthority;
  import org.springframework.security.core.authority.SimpleGrantedAuthority;
  import org.springframework.security.core.context.SecurityContextHolder;
  import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
  
  import com.bolsadeideasspringboot.app.auth.SimpleGrantedAuthoritiesMixin;
  import com.fasterxml.jackson.databind.ObjectMapper;
  
  import io.jsonwebtoken.Claims;
  import io.jsonwebtoken.JwtException;
  import io.jsonwebtoken.Jwts;
  
  public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
  
  public JWTAuthorizationFilter(AuthenticationManager authenticationManager) {
      super(authenticationManager);
      // TODO Auto-generated constructor stub
  }
  
  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
          throws IOException, ServletException {
  
      String header = request.getHeader("Authorization");
  
      if(!requiresAuthentication(header)) {
          chain.doFilter(request, response);
          return;
      }
  
      boolean tokenValid;
      Claims token = null;
  
      try {
          token = Jwts.parser()
          .setSigningKey("Clave!#$%&amp;/()Secreta.//1234.4321.//.abcd.dcba.1a.2b.3c.4d.12345678".getBytes())
          .parseClaimsJws(header.replace("Bearer ", "")).getBody();
          tokenValid = true;
      }
      catch(JwtException e) {
          tokenValid = false;
      }
  
      UsernamePasswordAuthenticationToken authentication = null;
  
      if(tokenValid) {
  
          String username = token.getSubject();
          Object roles = token.get("authorities");
  
          Collection&lt;? extends GrantedAuthority&gt; authorities = Arrays.asList(new ObjectMapper()
                  .addMixIn(SimpleGrantedAuthority.class, SimpleGrantedAuthoritiesMixin.class)
                  .readValue(roles.toString().getBytes(), SimpleGrantedAuthority[].class));
  
          authentication = new UsernamePasswordAuthenticationToken(username, null, authorities);
  
      }
  
      SecurityContextHolder.getContext().setAuthentication(authentication);
      chain.doFilter(request, response);
  
  
  }
  
  protected boolean requiresAuthentication(String header) {
      if (header == null || !header.toLowerCase().startsWith("Bearer ")) {
  
          return false;
      }
      return true;
  }   
  }
  </code></pre>
  
  <p>So, basically, when i try to log in in the login route ("<a href="http://127.0.0.1:8080/api/login" rel="nofollow noreferrer">http://127.0.0.1:8080/api/login</a>"), it works, the app generates the token</p>
  
  <p><a href="https://i.stack.imgur.com/eBxHv.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/eBxHv.png" alt="enter image description here"></a></p>
  
  <p>but, when i try to send the credentials to the ("<a href="http://127.0.0.1:8080/api/cliente/listar" rel="nofollow noreferrer">http://127.0.0.1:8080/api/cliente/listar</a>"), i get the 403 error every single time</p>
  
  <p><a href="https://i.stack.imgur.com/TCMZa.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/TCMZa.png" alt="enter image description here"></a></p>
  
  <p>Any help would be appreciated, once again, i'm a rookie in java, so please bear with me, thanks.</p>