Ручная аутентификация контекста безопасности Spring дает странные результаты - PullRequest
0 голосов
/ 20 июня 2019

Я добавил весеннюю аутентификацию вручную в вызовах служб rest / soap, перехватывая входящие запросы rest / soap, используя HandlerInterceptor и SoapHandler.Я отправляю свое зарегистрированное имя пользователя от клиента веб-сервису, добавляя его в заголовок soap / rest.Я перехватываю входящий запрос и устанавливаю ручную аутентификацию.Когда я обнаружил, что аутентификация уже есть, я пропускаю настройку.Я предполагаю, что для каждого нового запроса rest / soap не будет аутентификации на веб-сервисе (на стороне сервера).Это дает мне имя пользователя, который не является текущим пользователем для нового запроса.

public UserDetails getUser() {

    Authentication auth = SecurityContextHolder.getContext().getAuthentication();

    UserDetails user= null;
    if (auth != null && !(auth instanceof AnonymousAuthenticationToken)) {
        // userDetails = auth.getPrincipal()

        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        String username = null;
        if (principal instanceof UserDetails) {
            username = ((UserDetails) principal).getUsername();
            user= (UserDetails ) principal;

        } else {
            username = principal.toString();
        }       
    }

    return user;
}

public void setUser(String username) {

    // creating spring security context manually

    try {
        // Must be called from request filtered by Spring Security,
        // otherwise SecurityContextHolder is not updated
        List<SimpleGrantedAuthority> grantedAuthorities = new ArrayList<SimpleGrantedAuthority>();
        Authentication authentication;
        authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication != null && !(authentication instanceof AnonymousAuthenticationToken)) {
            Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            UserDetails user;

            String uname;
            if (principal instanceof UserDetails) {
                user= (User) principal;
                uname = user.getUsername();                 
            } else {
                uname = principal.toString();
            }
            LOGGER.info("Found username in Spring context: " + uname);
        } else {
            LOGGER.info("Spring context not found: ");
            LOGGER.info("Setting manual authentication.. Username: " + username);
            // grantedAuthorities.add(new SimpleGrantedAuthority("USER"));
            UserDetails contextUser = new User(username, username, true, true, true, true,
                    grantedAuthorities, null);
            authentication = new UsernamePasswordAuthenticationToken(contextUser, username, grantedAuthorities);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
    } catch (Exception e) {
        SecurityContextHolder.getContext().setAuthentication(null);
        LOGGER.error("Failure in creating spring security context authentication", e);
    }
}

1 Ответ

1 голос
/ 20 июня 2019

Это потому, что SecurityContext хранится в ThreadLocal, и вы никогда не очищали его от ThreadLocal после того, как поток веб-службы завершит обработку запроса, что означает, что этот же поток используется для обработки следующего запроса., он по-прежнему сохраняет SecurityContext предыдущего запроса. Чтобы быть точным, он всегда сохраняет пользователя, который первым использует эту нить в вашем случае.

Быстрое решение состоит в том, что вы должны очистить SecurityContext после выполнения каждого запроса:

SecurityContextHolder.clearContext();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...