Reputation: 105
I'm currently making an E-Commerce application and I'm trying to add "Add To Cart" functionality. I haven't yet worked with httprequests, so everyone has to login before accessing the website.
When a user logs in, goes onto the home page and tries to add a product to cart, it will send a post request to add that product.
@PostMapping("/cart/{id}")
public String addProduct(@PathVariable Long id, @ModelAttribute("cartItem") CartItems cartItem, Model model) {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
User user = ((User) principal);
Optional<Product> product = productService.findById(id);
cartItem.setProduct(product.get());
cartItem.setPrice(cartItem.getQuantity() * cartItem.getProduct().getPrice());
user.getCart().getCartItems().add(cartItem);
return "redirect:/cart";
}
User Class:
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "users")
public class User implements Serializable, UserDetails
{
private static final long serialVersionUID = -8903772563656397127L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long id;
@Column(name = "username")
private String username;
@Column(name = "email")
private String email;
@Column(name = "password")
private String password;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@OneToOne(mappedBy = "user")
private Cart cart;
@Column(name = "address")
private String address;
USER DETAILS:
@Override
@Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userService.findByUsername(username);
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
grantedAuthorities.add(new SimpleGrantedAuthority("UNDEFINED"));
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), grantedAuthorities);
}
The problem is casting the User class to Object principal from user details. I am getting the following error:
java.lang.ClassCastException: class org.springframework.security.core.userdetails.User cannot be cast to class com.nickjojo.ecomapp.entity.User (org.springframework.security.core.userdetails.User and com.nickjojo.ecomapp.entity.User are in unnamed module of loader 'app')
Upvotes: 0
Views: 4627
Reputation: 3724
There's a couple of things I would improve here:
Your User
class already implements UserDetails
, so no need to convert it to a org.springframework.User in your UserDetailsService.loadUserByUsername
. Simply return it.
Instead of going through the SecurityContext, you can then simply go with the @AuthenticationPrincipal
annotation like so (note, it will be null if the user is not logged in):
@PostMapping("/cart/{id}")
public String addProduct(... @AuthenticationPrincipal user) {
// ...
}
Upvotes: 1
Reputation: 105
I found the answer. I was casting User to the principle object, but instead I casted UserDetails to the object (they can be casted together), then got the object's username as specified as one of the fields when returning a UserDetails object in the UserDetailsService class. I then used that username to find the user through my service.
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username = ((UserDetails) principal).getUsername();
User user = userService.findByUsername(username);
Upvotes: 1