Поделиться через


Руководство по разработке с использованием Spring Boot Starter для Microsoft Entra

В этой статье описываются функции и основные сценарии начального средства Spring Boot для идентификатора Microsoft Entra. В статье также содержатся рекомендации по общим проблемам, обходным решениям и диагностическим шагам.

При создании веб-приложения идентификация и управление доступом являются основными элементами. Azure предлагает облачную службу удостоверений, которая имеет глубокую интеграцию с остальной частью экосистемы Azure.

Несмотря на то, что Spring Security упрощает защиту приложений Spring, она не адаптирована к конкретному поставщику удостоверений. Начальный код Spring Boot для Microsoft Entra ID позволяет подключить веб-приложение к клиенту Microsoft Entra и защитить сервер ресурсов с помощью идентификатора Microsoft Entra. Он использует протокол Oauth 2.0 для защиты веб-приложений и серверов ресурсов.

Следующие ссылки предоставляют доступ к начальнму пакету, документации и примерам:

Необходимые условия

Чтобы выполнить инструкции в этом руководстве, необходимо иметь следующие предварительные требования:

Важный

Для выполнения действий, описанных в этой статье, требуется spring Boot версии 2.5 или более поздней.

Основные сценарии

В этом руководстве описывается использование начального средства Microsoft Entra в следующих сценариях:

Веб-приложение — это любое веб-приложение, которое позволяет пользователю входить в систему. Сервер ресурсов будет принимать или запрещать доступ, после проверки токена доступа.

Доступ к веб-приложению

В этом сценарии используется поток предоставления кода авторизации OAuth 2.0 для входа пользователя с помощью учетной записи Майкрософт.

Чтобы использовать стартовый пакет Microsoft Entra в этом сценарии, выполните следующие действия.

Задайте URI перенаправления на <application-base-uri>/login/oauth2/code/. Например, http://localhost:8080/login/oauth2/code/. Не забудьте включить конечный символ /. Дополнительные сведения о URI перенаправления см. в разделе Добавление URI перенаправления в Краткое руководство: регистрация приложения на платформе удостоверений Майкрософт.

Снимок экрана портала Azure, показывающий страницу аутентификации веб-приложения с выделенным адресом перенаправления.

Добавьте следующие зависимости в файл pom.xml .

<dependency>
   <groupId>com.azure.spring</groupId>
   <artifactId>spring-cloud-azure-starter-active-directory</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

Заметка

Дополнительные сведения об управлении версиями библиотеки Azure Spring Cloud с помощью счета за материалы (BOM) см. в разделе " Начало работы " руководства разработчика Azure Spring Cloud.

Добавьте следующие свойства в файл application.yml . Значения этих свойств можно получить из регистрации приложения, созданной на портале Azure, как описано в предварительных требованиях.

spring:
 cloud:
   azure:
     active-directory:
       enabled: true
       profile:
         tenant-id: <tenant>
       credential:
         client-id: <your-client-ID>
         client-secret: <your-client-secret>

Заметка

Значения, допустимые для tenant-id: common, organizations, consumersили идентификатор клиента. Дополнительные сведения об этих значениях см. в разделе Использована неправильная конечная точка (личные и учетные записи организации) документа Ошибка AADSTS50020 - Учетная запись пользователя от поставщика удостоверений не существует в клиенте. Для получения информации о преобразовании однотенантного приложения в мультитенантное см. Преобразование однотенантного приложения в мультитенантное в Microsoft Entra ID.

Используйте конфигурацию безопасности по умолчанию или укажите собственную конфигурацию.

Вариант 1. Используйте конфигурацию по умолчанию.

С помощью этого параметра вам не нужно ничего делать. Класс DefaultAadWebSecurityConfiguration настраивается автоматически.

Вариант 2. Укажите самоопределимую конфигурацию.

Чтобы предоставить конфигурацию, примените метод AadWebApplicationHttpSecurityConfigurer#aadWebApplication для HttpSecurity, как показано в следующем примере:

@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
@EnableMethodSecurity
public class AadOAuth2LoginSecurityConfig {

   /**
    * Add configuration logic as needed.
    */
   @Bean
   SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
       http.apply(AadWebApplicationHttpSecurityConfigurer.aadWebApplication())
               .and()
           .authorizeHttpRequests()
               .anyRequest().authenticated();
           // Do some custom configuration.
       return http.build();
   }
}

Доступ к серверам ресурсов из веб-приложения

Чтобы использовать стартовый пакет Microsoft Entra в этом сценарии, выполните следующие действия.

Задайте URI перенаправления, как описано ранее.

Добавьте следующие зависимости в файл pom.xml .

<dependency>
   <groupId>com.azure.spring</groupId>
   <artifactId>spring-cloud-azure-starter-active-directory</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

Заметка

Дополнительные сведения об управлении версиями библиотеки Azure Spring Cloud с помощью счета за материалы (BOM) см. в разделе " Начало работы " руководства разработчика Azure Spring Cloud.

Добавьте следующие свойства в файл application.yml , как описано ранее:

spring:
 cloud:
   azure:
     active-directory:
       enabled: true
       profile:
         tenant-id: <tenant>
       credential:
         client-id: <your-client-ID>
         client-secret: <your-client-secret>
       authorization-clients:
         graph:
           scopes: https://graph.microsoft.com/Analytics.Read, email

Заметка

Значения, допустимые для tenant-id: common, organizations, consumersили идентификатор клиента. Дополнительные сведения об этих значениях см. в разделе Использована неправильная конечная точка (личные и учетные записи организации) документа Ошибка AADSTS50020 - Учетная запись пользователя от поставщика удостоверений не существует в клиенте. Для получения информации о преобразовании однотенантного приложения в мультитенантное см. Преобразование однотенантного приложения в мультитенантное в Microsoft Entra ID.

Здесь graph — это имя OAuth2AuthorizedClient, а scopes — это области, необходимые для предоставления согласия при входе.

Добавьте код в приложение, аналогичное следующему примеру:

@GetMapping("/graph")
@ResponseBody
public String graph(
   @RegisteredOAuth2AuthorizedClient("graph") OAuth2AuthorizedClient graphClient
) {
   // toJsonString() is just a demo.
   // oAuth2AuthorizedClient contains access_token. We can use this access_token to access the resource server.
   return toJsonString(graphClient);
}

Здесь graph — это идентификатор клиента, настроенный на предыдущем шаге. OAuth2AuthorizedClient содержит маркер доступа, который используется для доступа к серверу ресурсов.

Полный пример, демонстрирующий этот сценарий, см. в примере spring-cloud-azure-starter-active-directory: aad-web-application.

Защита сервера ресурсов или API

Этот сценарий не поддерживает вход, но защищает сервер, проверяя маркер доступа. Если маркер доступа действителен, сервер обслуживает запрос.

Чтобы использовать стартовый пакет Microsoft Entra в этом сценарии, выполните следующие действия.

Добавьте следующие зависимости в файл pom.xml .

<dependency>
   <groupId>com.azure.spring</groupId>
   <artifactId>spring-cloud-azure-starter-active-directory</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

Заметка

Дополнительные сведения об управлении версиями библиотеки Azure Spring Cloud с помощью счета за материалы (BOM) см. в разделе " Начало работы " руководства разработчика Azure Spring Cloud.

Добавьте следующие свойства в файл application.yml , как описано ранее:

spring:
 cloud:
   azure:
     active-directory:
       enabled: true
       credential:
         client-id: <your-client-ID>
       app-id-uri: <your-app-ID-URI>

Для проверки маркера доступа можно использовать значения <your-client-ID> и <your-app-ID-URI>. Вы можете получить значение <your-app-ID-URI> на портале Azure, как показано на следующих изображениях:

Скриншот портала Azure, показывающий страницу веб-приложения

Используйте конфигурацию безопасности по умолчанию или укажите собственную конфигурацию.

Вариант 1. Используйте конфигурацию по умолчанию.

С помощью этого параметра вам не нужно ничего делать. Класс DefaultAadResourceServerConfiguration настраивается автоматически.

Вариант 2. Укажите самоопределимую конфигурацию.

Чтобы предоставить конфигурацию, примените метод AadResourceServerHttpSecurityConfigurer#aadResourceServer для HttpSecurity, как показано в следующем примере:

@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
@EnableMethodSecurity
public class AadOAuth2ResourceServerSecurityConfig {

   /**
    * Add configuration logic as needed.
    */
   @Bean
   public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
       http.apply(AadResourceServerHttpSecurityConfigurer.aadResourceServer())
               .and()
           .authorizeHttpRequests()
               .anyRequest().authenticated();
       return http.build();
   }
}

Полный пример, демонстрирующий этот сценарий, см. в примере spring-cloud-azure-starter-active-directory: aad-resource-server.

Доступ к другим серверам ресурсов с сервера ресурсов

Этот сценарий поддерживает сервер ресурсов, посещающий другие серверы ресурсов.

Чтобы использовать стартовый пакет Microsoft Entra в этом сценарии, выполните следующие действия.

Добавьте следующие зависимости в файл pom.xml .

<dependency>
   <groupId>com.azure.spring</groupId>
   <artifactId>spring-cloud-azure-starter-active-directory</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

Заметка

Дополнительные сведения об управлении версиями библиотеки Azure Spring Cloud с помощью счета за материалы (BOM) см. в разделе " Начало работы " руководства разработчика Azure Spring Cloud.

Добавьте следующие свойства в файл application.yml :

spring:
 cloud:
   azure:
     active-directory:
       enabled: true
       profile:
         tenant-id: <tenant>
       credential:
         client-id: <web-API-A-client-ID>
         client-secret: <web-API-A-client-secret>
       app-id-uri: <web-API-A-app-ID-URI>
       authorization-clients:
         graph:
           scopes:
              - https://graph.microsoft.com/User.Read

Заметка

Значения, допустимые для tenant-id: common, organizations, consumersили идентификатор клиента. Дополнительные сведения об этих значениях см. в разделе Использована неправильная конечная точка (личные и учетные записи организации) документа Ошибка AADSTS50020 - Учетная запись пользователя от поставщика удостоверений не существует в клиенте. Для получения информации о преобразовании однотенантного приложения в мультитенантное см. Преобразование однотенантного приложения в мультитенантное в Microsoft Entra ID.

Используйте атрибут @RegisteredOAuth2AuthorizedClient в коде для доступа к связанному серверу ресурсов, как показано в следующем примере:

@PreAuthorize("hasAuthority('SCOPE_Obo.Graph.Read')")
@GetMapping("call-graph")
public String callGraph(@RegisteredOAuth2AuthorizedClient("graph") OAuth2AuthorizedClient graph) {
   return callMicrosoftGraphMeEndpoint(graph);
}

Полный пример, демонстрирующий этот сценарий, см. в примере spring-cloud-azure-starter-active-directory: aad-resource-server-obo.

Веб-приложение и сервер ресурсов в одном приложении

Этот сценарий поддерживает доступ к веб-приложению и защите сервера ресурсов или API в одном приложении.

Чтобы использовать aad-starter в этом сценарии, выполните следующие действия.

Добавьте следующие зависимости в файл pom.xml .

<dependency>
   <groupId>com.azure.spring</groupId>
   <artifactId>spring-cloud-azure-starter-active-directory</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

Заметка

Дополнительные сведения об управлении версиями библиотеки Azure Spring Cloud с помощью счета за материалы (BOM) см. в разделе " Начало работы " руководства разработчика Azure Spring Cloud.

Обновите файл application.yml . Задайте для свойства spring.cloud.azure.active-directory.application-type значение web_application_and_resource_serverи укажите тип авторизации для каждого клиента авторизации, как показано в следующем примере.

spring:
 cloud:
   azure:
     active-directory:
       enabled: true
       profile:
         tenant-id: <tenant>
       credential:
         client-id: <Web-API-C-client-id>
         client-secret: <Web-API-C-client-secret>
       app-id-uri: <Web-API-C-app-id-url>
       application-type: web_application_and_resource_server  # This is required.
       authorization-clients:
         graph:
           authorizationGrantType: authorization_code  # This is required.
           scopes:
             - https://graph.microsoft.com/User.Read
             - https://graph.microsoft.com/Directory.Read.All

Заметка

Значения, допустимые для tenant-id: common, organizations, consumersили идентификатор клиента. Дополнительные сведения об этих значениях см. в разделе Использована неправильная конечная точка (личные и учетные записи организации) документа Ошибка AADSTS50020 - Учетная запись пользователя от поставщика удостоверений не существует в клиенте. Для получения информации о преобразовании однотенантного приложения в мультитенантное см. Преобразование однотенантного приложения в мультитенантное в Microsoft Entra ID.

Напишите код Java для настройки нескольких экземпляров HttpSecurity.

В следующем примере кода AadWebApplicationAndResourceServerConfig содержит два цепочки фильтров безопасности, один для сервера ресурсов и один для веб-приложения. apiFilterChain bean имеет высокий приоритет в настройке конфигуратора безопасности сервера ресурсов. htmlFilterChain bean имеет низкий приоритет для настройки построителя безопасности веб-приложений.

@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
@EnableMethodSecurity
public class AadWebApplicationAndResourceServerConfig {

    @Bean
    @Order(1)
    public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
        http.apply(AadResourceServerHttpSecurityConfigurer.aadResourceServer())
                .and()
            // All the paths that match `/api/**`(configurable) work as the resource server. Other paths work as the web application.
            .securityMatcher("/api/**")
            .authorizeHttpRequests()
                .anyRequest().authenticated();
        return http.build();
    }

    @Bean
    public SecurityFilterChain htmlFilterChain(HttpSecurity http) throws Exception {
        // @formatter:off
        http.apply(AadWebApplicationHttpSecurityConfigurer.aadWebApplication())
                .and()
            .authorizeHttpRequests()
                .requestMatchers("/login").permitAll()
                .anyRequest().authenticated();
        // @formatter:on
        return http.build();
    }
}

Тип приложения

Свойство spring.cloud.azure.active-directory.application-type является необязательным, так как его значение можно вывести по зависимостям. Необходимо вручную задать свойство только при использовании значения web_application_and_resource_server.

Имеет зависимость: spring-security-oauth2-client Имеет зависимость: spring-security-oauth2-resource-server Допустимые значения типа приложения Значение по умолчанию
Да Нет web_application web_application
Нет Да resource_server resource_server
Да Да web_application,resource_server,
resource_server_with_obo, web_application_and_resource_server
resource_server_with_obo

Настраиваемые свойства

Начальный код Spring Boot для Идентификатора Microsoft Entra предоставляет следующие свойства:

Свойства Описание
spring.cloud.azure.active-directory.app-id-uri Используется сервером ресурсов для валидации аудитории в токене доступа. Маркер доступа действителен только в том случае, если аудитория равна значениям <your-client-ID> или <your-app-ID-URI>, описанным ранее.
spring.cloud.azure.active-directory.authorization-клиенты Схема, которая настраивает API ресурсов, которые приложение будет использовать. Каждый элемент соответствует одному ресурсу API, который будет посещать приложение. В коде Spring каждый элемент соответствует одному объекту OAuth2AuthorizedClient.
spring.cloud.azure.active-directory.authorization-client.<your-client-name>. Области Разрешения API сервера ресурсов, которые приложение собирается получить.
spring.cloud.azure.active-directory.authorization-clients.<your-client-name>.тип авторизации-предоставления Тип клиента авторизации. Поддерживаемые типы — это authorization_code (тип по умолчанию для веб-приложения), on_behalf_of (тип по умолчанию для resource-server), client_credentials.
spring.cloud.azure.active-directory.application-type Обратитесь к типу приложения.
spring.cloud.azure.active-directory.profile.environment.active-directory-endpoint Базовый универсальный код ресурса (URI) для сервера авторизации. Значение по умолчанию — https://login.microsoftonline.com/.
spring.cloud.azure.active-directory.credential.client-id Идентификатор зарегистрированного приложения в Microsoft Entra ID.
spring.cloud.azure.active-directory.credential.client-secret Секретный ключ клиента зарегистрированного приложения.
spring.cloud.azure.active-directory.user-group.use-транзитивные-участники Используйте v1.0/me/transitiveMemberOf, чтобы получить группы, если задано значение true. В противном случае используйте /v1.0/me/memberOf.
spring.cloud.azure.active-directory.post-logout-redirect-uri URI перенаправления для отправки выхода из системы.
spring.cloud.azure.active-directory.profile.tenant-id Идентификатор клиента Azure. Значения, допустимые для tenant-id: common, organizations, consumersили идентификатор клиента.
spring.cloud.azure.active-directory.user-group.allowed-group-group-name Ожидаемые группы пользователей, которым будет предоставлен доступ, если он найден в ответе на вызов Graph API MemberOf.
spring.cloud.azure.active-directory.user-name-attribute Указывает, какое утверждение будет использоваться в качестве имени принципала.

В следующих примерах показано, как использовать эти свойства:

Пример свойства 1. Чтобы использовать Azure China 21Vianet вместо Azure Global, используйте следующий шаг.

  • Добавьте следующие свойства в файл application.yml :

    spring:
       cloud:
         azure:
           active-directory:
             enabled: true
             profile:
               environment:
                 active-directory-endpoint: https://login.partner.microsoftonline.cn
    

С помощью этого метода можно использовать суверенное или национальное облако Azure вместо общедоступного облака Azure.

Пример свойства 2. Чтобы использовать имя группы для защиты некоторых методов в веб-приложении, выполните следующие действия.

Добавьте следующее свойство в файл application.yml :

spring:
 cloud:
   azure:
     active-directory:
       enabled: true
       user-group:
         allowed-groups: group1, group2

Используйте конфигурацию безопасности по умолчанию или укажите собственную конфигурацию.

Вариант 1. Используйте конфигурацию по умолчанию. С помощью этого параметра вам не нужно ничего делать. Класс DefaultAadWebSecurityConfiguration настраивается автоматически.

Вариант 2. Укажите самоопределимую конфигурацию. Чтобы предоставить конфигурацию, примените метод AadWebApplicationHttpSecurityConfigurer#aadWebApplication для HttpSecurity, как показано в следующем примере:

@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
@EnableMethodSecurity
public class AadOAuth2LoginSecurityConfig {

   /**
    * Add configuration logic as needed.
    */
   @Bean
   public SecurityFilterChain htmlFilterChain(HttpSecurity http) throws Exception {
       // @formatter:off
       http.apply(AadWebApplicationHttpSecurityConfigurer.aadWebApplication())
               .and()
           .authorizeHttpRequests()
               .anyRequest().authenticated();
       // @formatter:on
       // Do some custom configuration.
       return http.build();
   }
}

Используйте заметку @PreAuthorize для защиты метода, как показано в следующем примере:

@Controller
public class RoleController {
   @GetMapping("group1")
   @ResponseBody
   @PreAuthorize("hasRole('ROLE_group1')")
   public String group1() {
       return "group1 message";
   }

   @GetMapping("group2")
   @ResponseBody
   @PreAuthorize("hasRole('ROLE_group2')")
   public String group2() {
       return "group2 message";
   }

   @GetMapping("group1Id")
   @ResponseBody
   @PreAuthorize("hasRole('ROLE_<group1-id>')")
   public String group1Id() {
       return "group1Id message";
   }

   @GetMapping("group2Id")
   @ResponseBody
   @PreAuthorize("hasRole('ROLE_<group2-id>')")
   public String group2Id() {
       return "group2Id message";
   }
}

Пример свойства 3: Чтобы включить поток учетных данных клиента на сервере ресурсов, который взаимодействует с другими серверами ресурсов, выполните следующие действия.

Добавьте следующее свойство в файл application.yml :

spring:
 cloud:
   azure:
     active-directory:
       enabled: true
       authorization-clients:
         webapiC:   # When authorization-grant-type is null, on behalf of flow is used by default
           authorization-grant-type: client_credentials
           scopes:
             - <Web-API-C-app-id-url>/.default

Добавьте код в приложение, аналогичное следующему примеру:

@PreAuthorize("hasAuthority('SCOPE_Obo.WebApiA.ExampleScope')")
@GetMapping("webapiA/webapiC")
public String callClientCredential() {
   String body = webClient
       .get()
       .uri(CUSTOM_LOCAL_READ_ENDPOINT)
       .attributes(clientRegistrationId("webapiC"))
       .retrieve()
       .bodyToMono(String.class)
       .block();
   LOGGER.info("Response from Client Credential: {}", body);
   return "client Credential response " + (null != body ? "success." : "failed.");
}

Дополнительные функции

Обеспечение контроля доступа с использованием ID токена в веб-приложении

Стартер поддерживает создание GrantedAuthority из утверждения roles токена идентификатора для того, чтобы разрешить использование токена идентификатора для авторизации в веб-приложении. Функцию appRoles идентификатора Microsoft Entra ID можно использовать для создания утверждения roles и реализации управления доступом.

Заметка

Утверждение roles, созданное из appRoles, украшено префиксом APPROLE_.

При использовании appRoles в качестве требования roles не следует одновременно настраивать атрибут группы как roles. В противном случае атрибут группы переопределит утверждение, содержащее сведения о группе, а не appRoles. В манифесте следует избегать следующей конфигурации:

"optionalClaims": {
    "idtoken": [{
        "name": "groups",
        "additionalProperties": ["emit_as_roles"]
    }]
}

Чтобы поддерживать управление доступом по токену идентификатора в веб-приложении, выполните следующие действия.

Добавьте роли приложения в приложение и назначьте их пользователям или группам. Дополнительные сведения см. в статье "Практическое руководство. Добавление ролей приложения в приложение и их получение в токене".

Добавьте следующую конфигурацию appRoles в манифест приложения:

 "appRoles": [
   {
     "allowedMemberTypes": [
       "User"
     ],
     "displayName": "Admin",
     "id": "2fa848d0-8054-4e11-8c73-7af5f1171001",
     "isEnabled": true,
     "description": "Full admin access",
     "value": "Admin"
    }
 ]

Добавьте код в приложение, аналогичное следующему примеру:

@GetMapping("Admin")
@ResponseBody
@PreAuthorize("hasAuthority('APPROLE_Admin')")
public String Admin() {
   return "Admin message";
}

Устранение неполадок

Включение ведения журнала клиентов

Пакеты SDK Azure для Java предлагают согласованную историю ведения журнала для устранения неполадок и устранения ошибок приложений. Созданные журналы будут фиксировать поток приложения до достижения терминала, помогая найти основную проблему. Ознакомьтесь с вики-страницей по логированию, чтобы получить рекомендации по его включению.

Включите ведение журналирования Spring

Spring позволяет всем поддерживаемым системам логирования устанавливать уровни логирования в среде Spring, например, через application.properties, используя logging.level.<logger-name>=<level>, где <level> является одним из значений TRACE, DEBUG, INFO, WARN, ERROR, FATAL или OFF. Корневой логгер можно настроить с помощью logging.level.root.

В следующем примере показаны потенциальные параметры ведения журнала в файле application.properties :

logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR

Дополнительные сведения о настройке логирования в Spring см. в документации Spring.

Дальнейшие действия

Чтобы узнать больше о Spring и Azure, перейдите в центр документации Spring в Azure.