java - Spring Security如何将principal注入(inject)到Controller中?

标签 java spring spring-mvc spring-security

我可以像下面的代码一样获取用户主体,但我很困惑 Spring Security 如何知道注入(inject)正确的主体。通常,我们会传递 args 来调用带参数的方法。那么,Spring 在哪里调用带有主体参数的 Controller 方法呢?感谢您的帮助。

@ResponseBody
@RequestMapping({"/api/user"})
public Principal user(Principal principal) {
    return principal;
}

最佳答案

正如评论所说,HandlerMethodArgumentResolver是一个策略接口(interface),用于在给定请求的上下文中将方法参数解析为参数值。实际上,Principal 参数将在 ServletRequestMethodArgumentResolver 中解析。说话很便宜,并显示源代码。

@Override
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
        NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {

    Class<?> paramType = parameter.getParameterType();

    // WebRequest / NativeWebRequest / ServletWebRequest
    if (WebRequest.class.isAssignableFrom(paramType)) {
        if (!paramType.isInstance(webRequest)) {
            throw new IllegalStateException(
                    "Current request is not of type [" + paramType.getName() + "]: " + webRequest);
        }
        return webRequest;
    }

    // ServletRequest / HttpServletRequest / MultipartRequest / MultipartHttpServletRequest
    if (ServletRequest.class.isAssignableFrom(paramType) || MultipartRequest.class.isAssignableFrom(paramType)) {
        return resolveNativeRequest(webRequest, paramType);
    }

    // HttpServletRequest required for all further argument types
    return resolveArgument(paramType, resolveNativeRequest(webRequest, HttpServletRequest.class));
}

现在你可以看到关键代码为Principal.class.isAssignableFrom(paramType),如果你进一步查找,你可以看到代码SecurityContextHolder.getContext().getAuthentication () 来获取实际参数。好的,就这样,感谢 @chrylis -on Strike- 评论。

@Nullable
private Object resolveArgument(Class<?> paramType, HttpServletRequest request) throws IOException {
    //omitted......
    else if (Principal.class.isAssignableFrom(paramType)) {
        Principal userPrincipal = request.getUserPrincipal();
        if (userPrincipal != null && !paramType.isInstance(userPrincipal)) {
            throw new IllegalStateException(
                    "Current user principal is not of type [" + paramType.getName() + "]: " + userPrincipal);
        }
        return userPrincipal;
    }
    //omitted......
}

关于java - Spring Security如何将principal注入(inject)到Controller中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60751605/

相关文章:

java - 将列表映射到 map 中的 DTO - java

java - 单元测试实时/并发软件

Spring Web MVC : How to retrieve model (passed as map) in a view?

java - 如何在 Spring Security 中启用 POST、PUT 和 DELETE 方法

java - jdbcTemplate 为 null 并抛出空指针异常

java - Spring MVC AbstractXlsxView

java - 在使用 Jackson 时,我应该使用包装器还是原始类型作为字段

java - 带有请求参数的 ElasticSearch Java API

java - 使用具有多个实现的接口(interface)的 Spring 依赖注入(inject)

java - 动态更改 Spring bean 属性