Как мне расширить com.microsoft.azure.spring.autoconfigure.aad.UserPrincipal?

#java #spring-boot #azure-active-directory #msal #azure-spring-boot

#java #весенняя загрузка #azure-active-directory #msal #azure-spring-boot

Вопрос:

Я использую MSAL на интерфейсе (PKCE) и azure-active-directory-spring-boot-starter на сервере, чтобы предоставить объект, который представляет вошедшего в систему пользователя и его утверждения.

Я создал класс, который обертывает Microsoft UserPrincipal , чтобы обеспечить легкий доступ к известным заявлениям:

 import com.microsoft.azure.spring.autoconfigure.aad.UserPrincipal;
public class MyCustomUser {
    private UserPrincipal userPrincipal;

    public MyCustomUser(UserPrincipal userPrincipal) {
        this.userPrincipal = userPrincipal;
    }

    public String getEmployeeId() {
        return String.valueOf(this.userPrincipal.getClaim("emplid"));
    }
}
 

Я делаю это доступным через вспомогательный класс

 @Component
public class MyAppSecurityContext {
    public MyCustomUser getUser() {
        UserPrincipal principal = (UserPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        return new MyCustomUser(principal);
    }
}
 

а затем использовать его в моем сервисном уровне:

 @Service
public class AnnouncementServiceImpl implements AnnouncementService {

    @Autowired
    private MyAppSecurityContext securityContext;

    @Override
    public List<Announcement> saveAnnouncement(Announcement announcement) {
        MyCustomUser currentUser = this.securityContext.getUser();
        String empid = currentUser.getEmployeeId();

        return this.announcementRepository.saveAnnouncement(empid, announcement);
    }
}
 

Это работает, но кажется неправильным. Я бы предпочел иметь MyCustomUser extend UserPrincipal и getPrincipal() возвращать мой пользовательский тип (без эффективной повторной реализации моего собственного UserPrincipal ) вместо предоставления фасада перед объектом-членом. Проблема в том, что конструктор UserPrincipal ожидает проблем с JWT, что говорит о том, что это неправильный подход. Есть ли другой, более подходящий способ моделирования пользователя для проекта Spring security, который полагается только на утверждения на стороне клиента?

Комментарии:

1. Могу ли я узнать, что вы имели в виду под утверждениями на стороне клиента в своем вопросе? Поправьте меня, если я ошибаюсь, вы пытаетесь реализовать лучший способ доступа к утверждениям пользователей во всем приложении. Если это так, создайте модель для пользовательских утверждений, затем попробуйте использовать обработчик токенов или HTTP-обработчик, чтобы прочитать все утверждения и добавить данные в созданную модель. Эта модель может быть добавлена в контекст как элемент и может быть прочитана / доступна по всему проекту для этого контекста. Другой способ — использовать пользовательский graph API для получения информации о пользователе вместо доступа к утверждениям. Поправьте меня, если это не то, что вы ищете.

2. Я использую описанный здесь подход без состояния и пытаюсь максимально использовать работу MS (т.Е. UserPrincipal). Мой MyCustomUser выше делает то, что вы предлагаете, но это кажется неправильным, потому что это оболочка.

3. Привет @Josh, пожалуйста, попробуйте опубликовать эту проблему на github.com/Azure/azure-sdk-for-java/issues .

Ответ №1:

@Josh.

В azure-active-directory-spring-boot-starter , UserPrincipal используется в AADAuthenticationFilter и AADAppRoleStatelessAuthenticationFilter . Теперь оба из 2 фильтров устарели.

Не могли бы вы использовать последнюю версию azure-spring-boot-starter-active-diectory ? Который равен 3.7.0, и он работает для spring-boot: 2.5.0. Поскольку вы использовали UserPrincipal , ваше приложение является ресурсным сервером.

Вот документы: https://github.com/Azure/azure-sdk-for-java/tree/azure-spring-boot-starter-active-directory_3.7.0/sdk/spring/azure-spring-boot-starter-active-directory#accessing-a-resource-server

У нас есть несколько примеров. Ваше текущее приложение похоже на:

  1. https://github.com/Azure-Samples/azure-spring-boot-samples/tree/azure-spring-boot_3.6/aad/azure-spring-boot-sample-active-directory-resource-server-by-filter-stateless
  2. https://github.com/Azure-Samples/azure-spring-boot-samples/tree/azure-spring-boot_3.6/aad/azure-spring-boot-sample-active-directory-resource-server-by-filter

Но использование 2 устарело, я предлагаю вам изучить новый way:https://github.com/Azure-Samples/azure-spring-boot-samples/tree/azure-spring-boot_3.6/aad/azure-spring-boot-sample-active-directory-ресурс-сервер