Реализация основного интерфейса между Spring Security и OAuth2 с двумя отличиями - PullRequest
1 голос
/ 09 марта 2019

Было монолитное Java-приложение, настроенное Spring Security. Всякий раз, когда я хочу получить аутентифицированного пользователя, объект org.springframework.serurity.authentication.UsernamePasswordAuthenticationToken дает мне следующее:

User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();

Этот фрагмент кода работал правильно, пока я не изменил конфигурацию с Spring Security на Oauth2 .
Для OAuth2, org.springframework.serurity.oauth2.provider.OAuth2Authentication объект дает мне аутентифицированного пользователя как это:

OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication();
LinkedHashMap linkedHashMap = (LinkedHashMap) oAuth2Authentication.getUserAuthentication().getDetails();
return linkedHashMap.get("principal");

Таким образом, результатом SecurityContextHolder.getContext().getAuthentication().getPrincipal() является разница между OAuth2 и Spring Security .
В чем проблема:
Моя проблема в том, что
1- Я должен переписать каждый, где содержится SecurityContextHolder.getContext().getAuthentication().getPrincipal()
с

           Object obj = SecurityContextHolder.getContext().getAuthentication();
            if (obj instanceof OAuth2Authentication) {
                OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication();
                LinkedHashMap linkedHashMap = (LinkedHashMap) oAuth2Authentication.getUserAuthentication().getDetails();
                linkedHashMap.get("principal");
                LinkedHashMap  result = linkedHashMap.get("principal");
                User user = new User();
                user.setId((Integer)result.get("id"));
                user.setName((String)result.get("name"));
                //As same way to set other its attributes@@@@@@@@@@
                return user;
            } else
                return (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

2- Как видно из приведенного выше кода, который помечен @@@@@@@@@ , номер поля объекта User составляет около 20, поэтому я должен повторить user.setField(result.get("filed")) 20 раз, и это так утомительно.
Решение состоит в том, что мне нужно либо переписать код, описанный выше, либо что-то еще, чего я не знаю?

1 Ответ

2 голосов
/ 09 марта 2019

Да, действительно, обе эти аутентификации отличаются в Spring Security и Spring Oauth2.Вы можете создать некоторый класс @Service или @Component, который обрабатывает, возвращая вам то, что вы ищете.Затем он может быть введен / автоматически подключен, когда вам это нужно.Таким образом, в основном, этот новый класс становится единственным источником правды для получения вашего принципала.Если вам случится снова изменить реализацию безопасности, ваш код не должен быть затронут, потому что служба обработки безопасности отделена новым интерфейсом.

См. Пример ниже:

@Service
public class Oauth2PrincipalService implements PrincipalService {

  public User retreivePrincipalUser(){
    //retreive user stuff here as you need using the oauth2 code you provided..

  }

}
public interface PrincipalService {

  User retreivePrincipalUser();

}

...