JWT Example

@Component

public class ApiAuthenticationEntryPoint implements AuthenticationEntryPoint{

@Override

public void commence(HttpServletRequest request, HttpServletResponse response,

AuthenticationException authException) throws IOException, ServletException {

response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getLocalizedMessage());

}

}

ApiSecurityConfig class

@Configuration

@EnableWebSecurity

@EnableGlobalMethodSecurity(prePostEnabled = true)

public class ApiSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired

private UserAuthService userDetailsService;

@Autowired

private ApiAuthenticationEntryPoint unauthorizedHandler;

@Override

public void configure(WebSecurity web) throws Exception {

}

@Autowired

public void configure(AuthenticationManagerBuilder auth) throws Exception {

auth.userDetailsService(userDetailsService).passwordEncoder(encoder());

}

@Override

protected void configure(HttpSecurity http) throws Exception {

http.cors().and().csrf().disable().authorizeRequests()

.antMatchers(“/token/*”, “/signup”, “/api/public/**”, “/h2/**”).permitAll().anyRequest().authenticated()

.and().exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and().sessionManagement()

.sessionCreationPolicy(SessionCreationPolicy.STATELESS);

http.headers().frameOptions().sameOrigin();

http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);

}

@Bean

public JwtAuthenticationFilter authenticationTokenFilterBean() {

return new JwtAuthenticationFilter();

}

@Bean

@Override

public AuthenticationManager authenticationManagerBean() throws Exception {

return super.authenticationManagerBean();

}

@Bean

public static NoOpPasswordEncoder encoder() {

return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();

}

}

JwtAuthenticationFilter class

@Component

public class JwtAuthenticationFilter extends OncePerRequestFilter {

@Autowired

private JwtUtil jwtUtils;

@Autowired

private UserAuthService userDetailsService;

@Override

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)

throws ServletException, IOException {

try {

String jwt = parseJwt(request);

if (jwt != null && jwtUtils.validateToken(jwt)) {

String username = jwtUtils.getUser(jwt);

UserDetails userDetails = userDetailsService.loadUserByUsername(username);

UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(

userDetails, null, userDetails.getAuthorities());

authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

SecurityContextHolder.getContext().setAuthentication(authentication);

}

} catch (Exception e) {

logger.error(“Cannot set user authentication: {}”, e);

}

filterChain.doFilter(request, response);

}

private String parseJwt(HttpServletRequest request) {

// String headerAuth = request.getHeader(“Authorization”);

// if (StringUtils.hasText(headerAuth) && headerAuth.startsWith(“Bearer “)) {

// return headerAuth.substring(7, headerAuth.length());

// }

//

String headerAuth = request.getHeader(“JWT”);

if (StringUtils.hasText(headerAuth)) {

return headerAuth;

}

return null;

}

}

JwtUtil class

@Component

public class JwtUtil {

//take value from propertyfile

private String jwtSecret;

//take value from propertyfile

private int jwtExpirationMs;

public String getUser(final String token) {

return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject();

}

public String generateToken(String username) {

return Jwts.builder()

.setSubject((username))

.setIssuedAt(new Date())

.setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))

.signWith(SignatureAlgorithm.HS512, jwtSecret)

.compact();

}

public boolean validateToken(final String token) {

try {

Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token);

return true;

} catch (SignatureException e) {

} catch (MalformedJwtException e) {

} catch (ExpiredJwtException e) {

} catch (UnsupportedJwtException e) {

} catch (IllegalArgumentException e) {

}

return false;

}

}

UserAuthService class

@Service

public class UserAuthService implements UserDetailsService{

@Autowired

private UserRepo userRepo;

@Override

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

Optional<User> user = userRepo.findByUsername(username);

if(user.isPresent()) {

return user.get();

}else {

throw new UsernameNotFoundException(“User ID not found”);

}

}

public User loadUserByUserId(Integer id) {

Optional<User> user = userRepo.findById(id);

if(user.isPresent()) {

return user.get();

}else {

throw new UsernameNotFoundException(“User ID not found”);

}

}

}

User class

@Entity

@Table(name =”user_2") // use because user was not working

public class User implements UserDetails {

private static final long serialVersionUID = 1L;

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

private Integer userId;

@Column(unique=true)

private String username;

private String password;

@Enumerated(EnumType.STRING)

@CollectionTable(name=”user_role”,joinColumns=@JoinColumn(name = “user_id”))

@ElementCollection(targetClass = Role.class,fetch=FetchType.EAGER)

private Set<Role> roles;

@Override

public Collection<? extends GrantedAuthority> getAuthorities() {

return this.roles.stream().map(r -> new RoleGrantedAuthority(r.name())).collect(Collectors.toList());

}

@Override

public String getPassword() {

return this.password;

}

@Override

public String getUsername() {

return this.username;

}

@Override

public boolean isAccountNonExpired() {

return true;

}

@Override

public boolean isAccountNonLocked() {

return true;

}

@Override

public boolean isCredentialsNonExpired() {

return true;

}

@Override

public boolean isEnabled() {

return true;

}

//add getter setter, constructor

}

Role class

public enum Role {

CONSUMER,SELLER;

}

class RoleGrantedAuthority implements GrantedAuthority{

private static final long serialVersionUID = 1L;

public RoleGrantedAuthority(String role) {

super();

this.role = role;

}

String role;

@Override

public String getAuthority() {

return this.role;

}

}

PublicController ← containing login api

@RestController

@RequestMapping(“/api/public”)

public class PublicController {

@Autowired

AuthenticationManager authenticationManager;

@Autowired

private JwtUtil jwtUtils;

@Autowired

ProductRepo prepo;

@Autowired

private ProductRepo repo;

@GetMapping(“/product/search”)

public List<Product> getProduct(@RequestParam String keyword){

return repo.findByProductNameContainingIgnoreCaseOrCategoryCategoryNameContainingIgnoreCase(keyword, keyword);

}

@PostMapping(“/login”)

public ResponseEntity<String> login(@RequestBody Map<String ,String> map){

Authentication authentication = authenticationManager

.authenticate(new UsernamePasswordAuthenticationToken(map.get(“username”),map.get(“password”)));

SecurityContextHolder.getContext().setAuthentication(authentication);

User userDetails = (User) authentication.getPrincipal();

String jwtCookie = jwtUtils.generateToken(userDetails.getUsername());

return ResponseEntity.ok()

.body(jwtCookie);

}

}

SellerController

@RestController

@RequestMapping(“/api/auth/seller”)

@PreAuthorize(“hasAuthority(‘SELLER’)”)

public class SellerController {

@Autowired

ProductRepo prepo;

@PostMapping(“/product”)

public ResponseEntity<Object> postProduct(@RequestBody Product product) {

User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();

product.setSeller(user);

product.setCategory(product.getCategory());

Product p = prepo.save(product);

return ResponseEntity.created(ServletUriComponentsBuilder.fromCurrentRequest().path(“/{id}”).buildAndExpand(p.getProductId()).toUri()).build();

}

@GetMapping(“/product”)

public ResponseEntity<Object> getAllProducts(){

User userDetails = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

List<Product> product = prepo.findBySellerUserId(userDetails.getUserId());

return ResponseEntity.ok().body(product);

}

@GetMapping(“/product/{productId}”)

public ResponseEntity<Object> getProduct(@PathVariable Integer productId) {

User userDetails = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

Optional<Product> prop = prepo.findBySellerUserIdAndProductId(userDetails.getUserId(),productId);

if(!prop.isPresent()) {

return ResponseEntity.notFound().build();

}

return ResponseEntity.ok(prop.get());

}

@PutMapping(“/product”)

public ResponseEntity<Object> putProduct(@RequestBody Product product){

User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();

product.setSeller(user);

Optional<Product> p = prepo.findById(product.getProductId());

if(p.isPresent()) {

prepo.save(product);

return ResponseEntity.ok(“”);

}else {

return ResponseEntity.notFound().build();

}

}

@DeleteMapping(“/product/{productId}”)

public ResponseEntity<Object> deleteProduct(@PathVariable Integer productId){

User userDetails = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

Optional<Product> prop = prepo.findBySellerUserIdAndProductId(userDetails.getUserId(),productId);

if(prop.isPresent()) {

prepo.deleteById(productId);

return ResponseEntity.ok(“”);

}

return ResponseEntity.notFound().build();

}

}

Product Pojo

@Entity

public class Product {

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

private Integer productId;

private String productName;

private Double price;

@JsonIgnore

@JoinColumn(name=”seller_id”,referencedColumnName=”userId”,updatable=false)

@ManyToOne(cascade = CascadeType.PERSIST)

private User seller;

@JoinColumn(name=”category_id”,referencedColumnName=”categoryId”)

@ManyToOne(cascade = CascadeType.PERSIST,fetch = FetchType.EAGER)

private Category category;

//getter setter constructor

}

Category Pojo

@Entity

public class Category {

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

private Integer categoryId;

@Column(unique=true)

private String categoryName;

//getter setter constructor

}

Main class ← optional

@SpringBootApplication(scanBasePackages = “com.aj.ecommerce”)

@EnableJpaRepositories

@EnableTransactionManagement

public class EcommerceApplication {

public static void main(String[] args) {

SpringApplication.run(EcommerceApplication.class, args);

}

}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store