我注意到当我在RunAsManager中替换Authentication对象时,可解析的控制器方法参数(Authentication
,Principal
和@AuthenticationPrincipal
)忽略新的Authentication对象并接收原始的。
示例(所有4种方法都在同一个控制器中)
这解析为正确的(runAs)身份验证:
@Secured({"ROLE_ADMIN", "ROLE_WORKFLOW", "RUN_AS_USER"})
@PostMapping("/testRunAs")
public ResponseEntity<Result> testRunAs() {
Authentication authentication =
SecurityContextHolder.getContext().getAuthentication();
log.debug(authentication.getPrincipal().toString()); // correct
...
这些解析为错误的(原始)身份验证:
@Secured({"ROLE_ADMIN", "ROLE_WORKFLOW", "RUN_AS_USER"})
@PostMapping("/testRunAs1")
public ResponseEntity<Result> testRunAs1(Authentication authentication) {
log.debug(authentication.getPrincipal().toString()); // wrong
...
@Secured({"ROLE_ADMIN", "ROLE_WORKFLOW", "RUN_AS_USER"})
@PostMapping("/testRunAs2")
public ResponseEntity<Result> testRunAs2(Principal principal) {
log.debug(principal.toString()); // wrong
...
@Secured({"ROLE_ADMIN", "ROLE_WORKFLOW", "RUN_AS_USER"})
@PostMapping("/testRunAs3")
public ResponseEntity<Result> testRunAs3(@AuthenticationPrincipal User u) {
log.debug(u.toString()); // wrong
...
这怎么可能?
Spring resolveArgument
中的AuthenticationPrincipalArgumentResolver
方法显然
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
runAs
评估在Spring的beforeInvocation
AbstractSecurityInterceptor
进行
看起来argumentResolver在runAs替换之前执行,虽然我无法通过调试器确认(以某种方式无法在AuthenticationPrincipalArgumentResolver
中找到断点)
这是预期的行为吗?
注意:我使用的是Spring Security 4.2.3.RELEASE