Как Spring Security внедряет принципал в контроллер? - PullRequest
0 голосов
/ 19 марта 2020

Я могу получить пользовательский принципал как приведенный ниже код, но я озадачен тем, как Spring Security знает, как ввести правильный принципал. Обычно мы передаем аргументы для вызова метода с параметрами. Итак, где Spring вызывает метод контроллера с основными аргументами? Спасибо за любую помощь.

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

1 Ответ

0 голосов
/ 19 марта 2020

Как говорится в комментарии, HandlerMethodArgumentResolver - это интерфейс стратегии для преобразования параметров метода в значения аргумента в контексте данного запроса. На самом деле, основной аргумент будет разрешен в 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......
}
...