我知道您可以通过在Principal
中加入@GetMapping("/username")
@ResponseBody
public String currentUserName(Principal principal) {
return principal.getName();
}
作为方法参数来轻松获得用户名,例如:
MyCustomUser
但是我最终将要访问我使用findBy
方法从存储库实例化的principal.getName()
类的成员。我可以在Controller中放入一个辅助方法来进行查找并基于MyCustomUser
返回用户,但是我可以走得更远并直接绑定到@GetMapping("/stuff")
@ResponseBody
public String stuff(MyCustomUser user) {
return user.thing();
}
上,例如
@Component
public class PrincipalToMyCustomUserConverter implements Converter<Principal, MyCustomUser> {
private MyCustomUserRepository userRepository;
public PrincipalToApplicationUserConverter(MyCustomUserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public MyCustomUser convert(Principal source) {
return this.userRepository.findByUsername(source.getName());
}
}
我一直在寻找创建(Ref)这样的转换器:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: taskmanager-01
spec:
accessModes:
- ReadWriteOnce
storageClassName: managed-premium
resources:
requests:
storage: 16Gi
但是我不知道这是否是获取存储库的适当方法,并且我不知道在注册转换器(Ref)时如何通过存储库。
答案 0 :(得分:1)
您是正确的,因为您提出的转换器不合适。您的转换器可以将类型为<?xml version="1.0" encoding="UTF-8" standalone="yes"?><ElementName attribute1="A" attribute2="B"/>
的对象转换为类型为Principal
的对象,但是没有MyCustomUser
可以进行转换。主体注入背后的魔力在于,Spring实际上是从*Principal*
那里获得的,它不是从请求中反序列化的……尽管请求中存在的字段允许Spring创建SecurityContextHolder
。如果您确实想注入Principal
,请使用MyCustomUser
。 ModelAttribute
可用于所有Spring控制器方法。
我通常喜欢将这样的东西保留在自己的类中,因此我将定义一个将这个和其他@ControllerAdvice放在一个地方的类,就像这样:
ModelAttributes
以上内容足以使MyCustomUser可用于所有方法。我会注意到,您可能希望在此处进行一些错误处理,例如跳过如果Principal为null而不是其他情况,还可以让您的@ControllerAdvice
public class SomeControllerAdvice {
@Autowired
private MyCustomUserRepository myCustomUserRepository;
@ModelAttribute
public MyCustomUser getUser(Principal principal) {
return myCustomUserRepository.findByUsername(principal.getName());
}
}
方法返回Optional,以便您可以处理空的返回。