ClassCastException-用户的春季安全性

时间:2020-04-19 03:12:18

标签: spring spring-security

我当前正在制作一个电子商务应用程序,并且试图添加“添加到购物车”功能。我尚未使用httprequests,因此每个人都必须登录才能访问该网站。

用户登录后,进入主页并尝试将产品添加到购物车,它将发送发布请求以添加该产品。

    @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";
   }

用户类别:

@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;

用户详细信息:

    @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);
}

问题是从用户详细信息将User类转换为Object主体。我收到以下错误:

java.lang.ClassCastException:org.springframework.security.core.userdetails类。不能将用户转换为com.nickjojo.ecomapp.entity.User类(org.springframework.security.core.userdetails.User和com。 nickjojo.ecomapp.entity.User位于加载程序“ app”的未命名模块中)

2 个答案:

答案 0 :(得分:1)

在这里我需要改进几件事:

  1. 您的User类已经实现了UserDetails,因此无需将其转换为UserDetailsService.loadUserByUsername中的org.springframework.User。只需将其退回。

  2. 您无需像通过SecurityContext那样简单地使用@AuthenticationPrincipal注释,就像这样(注意,如果用户未登录,它将为null):

@PostMapping(“ /购物车/ {id}”)

public String addProduct(... @AuthenticationPrincipal user) {
// ...
}

答案 1 :(得分:0)

我找到了答案。我将User强制转换为基本对象,但是我将UserDetails强制转换为对象(它们可以一起强制转换),然后在返回UserDetailsS​​ervice类中的UserDetails对象时,将对象的用户名指定为字段之一。然后,我使用该用户名通过我的服务找到用户。

        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    String username = ((UserDetails) principal).getUsername();
    User user = userService.findByUsername(username);