title: How to implement JWT based authentication and authorization in Spring Security
body: <p><strong>How to implement JWT based authentication and authorization in Spring Security</strong></p>
  
  <p>I am trying to implement jwt based authentication and authorization in my spring boot app. I followed a tutorial written <a href="https://auth0.com/blog/implementing-jwt-authentication-on-spring-boot/" rel="nofollow noreferrer">here</a>. But it does not do anything in my app. It does not return jwt token rather I am authenticated and my request is fulfilled. I am new to spring security. here is my code.</p>
  
  <p>I want my app return jwt token and using the token the requests must be authorized.</p>
  
  <p>Here is my code.</p>
  
  <p><strong>JWTAuthenticationFilter.java</strong></p>
  
  <pre><code>import io.jsonwebtoken.Claims;
  import io.jsonwebtoken.Jwts;
  import io.jsonwebtoken.SignatureAlgorithm;
  
  public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
  
      private AuthenticationManager authenticationManager;
  
      @Autowired
      CustomUserDetailsService userService;
  
      public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
      this.authenticationManager = authenticationManager;
      }
  
      @Override
      public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
          throws AuthenticationException {
  
      try {
  
          CustomUserDetails user = new ObjectMapper().readValue(request.getInputStream(), CustomUserDetails.class);
  
          return authenticationManager.authenticate(
              new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), new ArrayList&lt;&gt;()));
      } catch (Exception e) {
      }
  
      return super.attemptAuthentication(request, response);
      }
  
      @Override
      protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
          Authentication auth) {
  
      String loggedInUser = ((CustomUserDetails) auth.getPrincipal()).getUsername();
  
      Claims claims = Jwts.claims().setSubject(loggedInUser);
  
      if (loggedInUser != null) {
          CustomUserDetails user = (CustomUserDetails) userService.loadUserByUsername(loggedInUser);
          String roles[] = {};
  
          for (Role role : user.getUser().getUserRoles()) {
          roles[roles.length + 1] = role.getRole();
          }
          claims.put("roles", roles);
  
          claims.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME));
  
      }
  
      String token = Jwts.builder().setClaims(claims)
          .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
          .signWith(SignatureAlgorithm.HS512, SECRET.getBytes()).compact();
      response.addHeader(HEADER_STRING, TOKEN_PREFIX + token);
  
      }
  
  }
  </code></pre>
  
  <p><strong>JWTAuthorizationFilter.java</strong></p>
  
  <pre><code>import io.jsonwebtoken.Claims;
  import io.jsonwebtoken.Jwts;
  
  public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
  
      public JWTAuthorizationFilter(AuthenticationManager authenticationManager) {
      super(authenticationManager);
  
      }
  
      @Override
      protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
          throws IOException, ServletException {
  
      String header = request.getHeader(HEADER_STRING);
      if (header == null || !header.startsWith(TOKEN_PREFIX)) {
          chain.doFilter(request, response);
          return;
      }
  
      UsernamePasswordAuthenticationToken authentication = getToken(request);
      SecurityContextHolder.getContext().setAuthentication(authentication);
      chain.doFilter(request, response);
  
      }
  
      @SuppressWarnings("unchecked")
      private UsernamePasswordAuthenticationToken getToken(HttpServletRequest request) {
  
      String token = request.getHeader(HEADER_STRING);
  
      System.out.println("-----------------------------------------------------");
      System.out.println("Token: " + token);
      System.out.println("-----------------------------------------------------");
  
      if (token != null) {
  
          Claims claims = Jwts.parser().setSigningKey(SECRET.getBytes())
              .parseClaimsJws(token.replace(TOKEN_PREFIX, "")).getBody();
          String user = claims.getSubject();
  
          ArrayList&lt;String&gt; roles = (ArrayList&lt;String&gt;) claims.get("roles");
  
          ArrayList&lt;MyGrantedAuthority&gt; rolesList = new ArrayList&lt;&gt;();
  
          if (roles != null) {
          for (String role : roles) {
              rolesList.add(new MyGrantedAuthority(role));
          }
          }
          if (user != null) {
          return new UsernamePasswordAuthenticationToken(user, null, null);
          }
          return null;
      }
      return null;
      }
  
  }
  </code></pre>
  
  <p><strong>SecurityConfig.java</strong></p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
      @Qualifier("userDetailsService")
      @Autowired
      CustomUserDetailsService userDetailsService;
  
      @Autowired
      PasswordEncoder passwordEncoder;
  
      @Autowired
      AuthenticationManager authenticationManager;
  
      @Autowired
      JWTAuthenticationEntryPoint jwtAuthenticationEntryPoint;
  
      @Autowired
      public void configureGlobal(AuthenticationManagerBuilder auth) {
      try {
          auth.userDetailsService(this.userDetailsService).passwordEncoder(passwordEncoder);
  
      } catch (Exception e) {
  
      }
  
      }
  
      /*
       * @Autowired public void configureGlobal(AuthenticationManagerBuilder auth)
       * throws Exception {
       * auth.inMemoryAuthentication().withUser("student").password("student").roles(
       * "student").and().withUser("admin") .password("admin").roles("admin"); }
       */
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
  
      http.csrf().disable();
      // http.authorizeRequests().anyRequest().permitAll();
  
      // http.authorizeRequests().antMatchers("/api/**").permitAll();
  
      http.addFilter(new JWTAuthenticationFilter(authenticationManager));
      http.addFilter(new JWTAuthorizationFilter(authenticationManager));
  
      http.authorizeRequests().antMatchers("/api/student/**").hasAnyRole("STUDENT", "ADMIN");
      http.authorizeRequests().antMatchers("/api/admin/**").hasRole("ADMIN");
      http.authorizeRequests().antMatchers("/api/libararian/**").hasAnyRole("LIBRARIAN", "ADMIN");
      http.authorizeRequests().antMatchers("/api/staff/**").hasAnyRole("STAFF", "ADMIN");
      http.authorizeRequests().antMatchers("/api/teacher/**").hasAnyRole("TEACHER", "ADMIN");
      http.authorizeRequests().antMatchers("/api/parent/**").hasAnyRole("PARENT", "ADMIN");
      http.httpBasic().authenticationEntryPoint(jwtAuthenticationEntryPoint);
  
      http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
  
      // http.formLogin().and().logout().logoutSuccessUrl("/login?logout").permitAll();
  
      }
  
  }
  </code></pre>
  
  <p><strong>MyGrantedAuthority.java</strong></p>
  
  <pre><code>    public class MyGrantedAuthority implements GrantedAuthority {
  
          String authority;
  
          MyGrantedAuthority(String authority) {
          this.authority = authority;
          }
  
          @Override
          public String getAuthority() {
          // TODO Auto-generated method stub
          return authority;
          }
  
      }
  </code></pre>
  
  <p><strong>JWTAuthenticationEntryPoint.java</strong></p>
  
  <pre><code>@Component
  public class JWTAuthenticationEntryPoint implements AuthenticationEntryPoint {
  
      @Override
      public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
          throws IOException, ServletException {
      response.setStatus(403);
      response.setContentType(MediaType.APPLICATION_JSON_VALUE);
  
      String message;
      if (exception.getCause() != null) {
          message = exception.getCause().getMessage();
      } else {
          message = exception.getMessage();
      }
      byte[] body = new ObjectMapper().writeValueAsBytes(Collections.singletonMap("error", message));
      response.getOutputStream().write(body);
      }
  
  }
  </code></pre>