【发布时间】:2022-09-28 04:02:59
【问题描述】:
我正在开发一个同时具有 REST 控制器和 Netflix DGS GraphQL 组件的 Spring Boot 服务。 REST 方法受 Spring Security 保护,每当需要当前用户名时,我使用 @AuthenticationPrincipal 注释添加一个方法参数,这使我可以访问经过身份验证的用户信息:
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
@RestController
public class ActionController {
@GetMapping(\"/getActions\")
public List<ActionResponse> getActions(@AuthenticationPrincipal UserDetails userDetails) {
return actionService.getActions(userDetails.getUsername());
}
}
现在我希望 GraphQL 方法具有相同的功能。但是当我尝试使用@AuthenticationPrincipal 参数时(如第一个示例),它总是等于null。我发现的解决方法是从 SecurityContextHolder 手动分配 userDetails:
import com.netflix.graphql.dgs.DgsComponent;
import com.netflix.graphql.dgs.DgsQuery;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
@DgsComponent
public class ActionDatafetcher {
@DgsQuery
public List<Map<String, Object>> actions(@AuthenticationPrincipal UserDetails userDetails) {
// The following line works well:
// userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username = userDetails.getUsername(); // ===> NullPointerException here
return actionService.getActionsMap(username);
}
}
如何让 @AuthenticationPrincipal 在 DgsComponent 中工作?
标签: java spring-boot authentication spring-security netflix-dgs