#Spring boot api with jwt

1 messages · Page 1 of 1 (latest)

tough turtle
#

I am making an API with spring boot 3 with jwt, by default the user logs in with the username of the user but I changed it to the email. But I think my implementation can be confusing, is there any other way to do this?
User Class

public class User implements UserDetails {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private String lastName;

    private String email;

    private String password;


    @CreationTimestamp
    @Column(updatable = false, name = "created_at")
    private Date createdAt;

    @UpdateTimestamp
    @Column(name = "updated_at")
    private Date updatedAt;

    // Methods from UserDetails interface
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return List.of();
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return email;
    }

    @Override
    public boolean isAccountNonExpired() {
        return UserDetails.super.isAccountNonExpired();
    }

    @Override
    public boolean isAccountNonLocked() {
        return UserDetails.super.isAccountNonLocked();
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return UserDetails.super.isCredentialsNonExpired();
    }

    @Override
    public boolean isEnabled() {
        return UserDetails.super.isEnabled();
    }
}

granite geyserBOT
# tough turtle I am making an API with spring boot 3 with jwt, by default the user logs in with...

Detected code, here are some useful tools:

Formatted code
public class User implements UserDetails {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
  private String name;
  private String lastName;
  private String email;
  private String password;
  @CreationTimestamp
  @Column(updatable = false, name = "created_at") private Date createdAt;
  @UpdateTimestamp
  @Column(name = "updated_at") private Date updatedAt;
  // Methods from UserDetails interface
  @Override
  public Collection<?  extends GrantedAuthority> getAuthorities() {
    return List.of();
  }
  @Override
  public String getPassword() {
    return password;
  }
  @Override
  public String getUsername() {
    return email;
  }
  @Override
  public boolean isAccountNonExpired() {
    return UserDetails.super .isAccountNonExpired();
  }
  @Override
  public boolean isAccountNonLocked() {
    return UserDetails.super .isAccountNonLocked();
  }
  @Override
  public boolean isCredentialsNonExpired() {
    return UserDetails.super .isCredentialsNonExpired();
  }
  @Override
  public boolean isEnabled() {
    return UserDetails.super .isEnabled();
  }
}
#

<@&1004656351647117403> please have a look, thanks.

tough turtle
#

Spring Security class

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        http.csrf(crsf -> crsf.disable())
                .authorizeHttpRequests(
                        (authorizeRequests) -> authorizeRequests
                                .requestMatchers("/api/v1/auth/**").permitAll()

                                .anyRequest().permitAll()


                ).sessionManagement(
                        (sessionManagement) -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                ).addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);




        return http.build();
    }

granite geyserBOT
# tough turtle Spring Security class ``` @Bean SecurityFilterChain securityFilterChain(...

Detected code, here are some useful tools:

Formatted code
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
  http.csrf(crsf -> crsf.disable()).authorizeHttpRequests((authorizeRequests) -> authorizeRequests.requestMatchers("/api/v1/auth/**").permitAll().anyRequest().permitAll()).sessionManagement((sessionManagement) -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)).addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class );
  return http.build();
}
tough turtle
#

Filter class

@Component
@AllArgsConstructor
public class JwtAuthFilter extends OncePerRequestFilter {


    private final JwtService jwtService;

    private final UserDetailsService userDetailsService;



    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        final String authHeader = request.getHeader("Authorization");
        final String jwt;
        final String userEmail;

        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            filterChain.doFilter(request, response);
            return;
        }

        jwt = authHeader.substring(7);
        userEmail = jwtService.extractEmail(jwt);

        if (userEmail != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(userEmail);
            if (jwtService.isTokenValid(jwt, userDetails)) {
                UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
                        userDetails,
                        null,
                        userDetails.getAuthorities()
                );
                authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authToken);
            }
        }
        filterChain.doFilter(request, response);
    }



}
granite geyserBOT
# tough turtle Filter class ``` @Component @AllArgsConstructor public class JwtAuthFilter exte...

Detected code, here are some useful tools:

Formatted code
@Component
@AllArgsConstructor
public class JwtAuthFilter extends OncePerRequestFilter {
  private final JwtService jwtService;
  private final UserDetailsService userDetailsService;
  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    final String authHeader = request.getHeader("Authorization");
    final String jwt;
    final String userEmail;
    if (authHeader == null  || !authHeader.startsWith("Bearer ")) {
      filterChain.doFilter(request, response);
      return ;
    }
    jwt = authHeader.substring(7);
    userEmail = jwtService.extractEmail(jwt);
    if (userEmail != null  && SecurityContextHolder.getContext().getAuthentication() == null ) {
      UserDetails userDetails = this .userDetailsService.loadUserByUsername(userEmail);
      if (jwtService.isTokenValid(jwt, userDetails)) {
        UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(userDetails, null , userDetails.getAuthorities());
        authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
        SecurityContextHolder.getContext().setAuthentication(authToken);
      }
    }
    filterChain.doFilter(request, response);
  }
}
tough turtle
#

jwt class


    public String extractEmail(String token) {
        return extractClaim(token, Claims::getSubject);
    }


    public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = extractAllClaims(token);
        return claimsResolver.apply(claims);
    }




    public String generateToken(String email) {
        return Jwts.builder()
                .subject(email)
                .issuedAt(new Date(System.currentTimeMillis()))
                .expiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) // 10 horas
                .signWith(getSignInKey())
                .compact();
    }


    public long getExpirationTime() {
        return jwtExpiration;
    }
    public boolean isTokenValid(String token, UserDetails userDetails) {
        final String email = extractEmail(token);
        System.out.println("email: isValid " + email);
        return (email.equals(userDetails.getUsername())) && !isTokenExpired(token);
    }

    private boolean isTokenExpired(String token) {
        return extractExpiration(token).before(new Date());
    }

    private Date extractExpiration(String token) {
        return extractClaim(token, Claims::getExpiration);
    }

    private Claims extractAllClaims(String token) {
        return Jwts
                .parser()
                .verifyWith(getSignInKey())
                .build()
                .parseSignedClaims(token)
                .getPayload();
    }

    private SecretKey getSignInKey() {
        byte[] keyBytes = Decoders.BASE64.decode(secretKey);
        return Keys.hmacShaKeyFor(keyBytes);
    }
granite geyserBOT
# tough turtle jwt class ``` public String extractEmail(String token) { return ex...

Detected code, here are some useful tools:

Formatted code
public String extractEmail(String token) {
  return extractClaim(token, Claims::getSubject);
}
public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
  final Claims claims = extractAllClaims(token);
  return claimsResolver.apply(claims);
}
public String generateToken(String email) {
  return Jwts.builder().subject(email).issuedAt(new Date(System.currentTimeMillis())).expiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) // 10 horas
  .signWith(getSignInKey()).compact();
}
public long getExpirationTime() {
  return jwtExpiration;
}
public boolean isTokenValid(String token, UserDetails userDetails) {
  final String email = extractEmail(token);
  System.out.println("email: isValid " + email);
  return (email.equals(userDetails.getUsername())) && !isTokenExpired(token);
}
private boolean isTokenExpired(String token) {
  return extractExpiration(token).before(new Date());
}
private Date extractExpiration(String token) {
  return extractClaim(token, Claims::getExpiration);
}
private Claims extractAllClaims(String token) {
  return Jwts.parser().verifyWith(getSignInKey()).build().parseSignedClaims(token).getPayload();
}
private SecretKey getSignInKey() {
  byte [] keyBytes = Decoders.BASE64.decode(secretKey);
  return Keys.hmacShaKeyFor(keyBytes);
}
granite geyserBOT