4.4 了解你的用户
4.4 了解你的用户
通常,仅仅知道用户已经登录是不够的。通常重要的是要知道他们是谁,这样才能调整他们的体验。
例如,在
为了在
@Data
@Entity
@Table(name="Taco_Order")
public class Order implements Serializable {
...
@ManyToOne
private User user;
...
}
此属性上的
在
有几种方法可以确定用户是谁。以下是一些最常见的方法:
- 将主体对象注入控制器方法
- 将身份验证对象注入控制器方法
- 使用
SecurityContext 获取安全上下文 - 使用
@AuthenticationPrincipal 注解的方法
例如,可以修改
@PostMapping
public String processOrder(@Valid Order order, Errors errors,
SessionStatus sessionStatus,
Principal principal) {
...
User user = userRepository.findByUsername(principal.getName());
order.setUser(user);
...
}
这可以很好地工作,但是它会将与安全性无关的代码与安全代码一起丢弃。可以通过修改
@PostMapping
public String processOrder(@Valid Order order, Errors errors,
SessionStatus sessionStatus,
Authentication authentication) {
...
User user = (User) authentication.getPrincipal();
order.setUser(user);
...
}
有了身份验证,可以调用
然而,也许最干净的解决方案是简单地接受
@PostMapping
public String processOrder(@Valid Order order, Errors errors,
SessionStatus sessionStatus,
@AuthenticationPrincipal User user) {
if (errors.hasErrors()) {
return "orderForm";
}
order.setUser(user);
orderRepo.save(order);
sessionStatus.setComplete();
return "redirect:/";
}
还有一种方法可以识别通过身份验证的用户是谁,尽管这种方法有点麻烦,因为它包含了大量与安全相关的代码。你可以从安全上下文获取一个认证对象,然后像这样请求它的主体:
Authentication authentication =
SecurityContextHolder.getContext().getAuthentication();
User user = (User) authentication.getPrincipal();
尽管这个代码段充满了与安全相关的代码,但是它与所描述的其他方法相比有一个优点:它可以在应用程序的任何地方使用,而不仅仅是在控制器的处理程序方法中,这使得它适合在较低级别的代码中使用。