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


Как зарегистрировать приложение в Azure AD RMS и обеспечить для него поддержку RMS

Важно!

Версии пакета SDK службы microsoft Rights Management, выпущенные до марта 2020 г., устарели; для использования выпуска за март 2020 г. необходимо обновить приложения, использующие более ранние версии. Полные сведения см. в уведомлении об устаревании.

Для пакета SDK службы Microsoft Rights Management не планируется никаких дополнительных улучшений. Мы настоятельно рекомендуем внедрить пакет SDK Microsoft Information Protection для классификации, маркировки и защиты.

Эта статья расскажет об основах регистрации приложений и обеспечения поддержки RMS через портал Azure, а также об обеспечении проверки подлинности пользователей с использованием библиотеки проверки подлинности Azure Active Directory (ADAL).

Что такое аутентификация пользователя

Аутентификация пользователя — это важный этап установки связи между приложением устройства и инфраструктурой служб RMS. Для процесса проверки подлинности используется стандартный протокол OAuth 2.0; для его работы требуются ключевые данные о текущем пользователе и запросе на проверку подлинности.

Регистрация через портал Azure

Начните с выполнения следующего руководства по настройке регистрации приложения с использованием портала Azure: Configure Azure RMS for ADAL authentication (Настройка Azure RMS на использование проверки подлинности ADAL). Не забудьте скопировать и сохранить идентификатор клиента и URI перенаправления, указанные в ходе этого процесса, для последующего использования.

Заключение соглашения об интеграции Information Protection (IPIA)

Перед развертыванием приложения необходимо заключить соглашение IPIA с группой Microsoft Information Protection. Дополнительные сведения см. в первой части статьи Развертывание в рабочей среде.

Реализация проверки подлинности пользователей для приложения

Интерфейс API служб RMS предусматривает обратный вызов, который должен быть реализован, чтобы обеспечить проверку подлинности пользователей. Пакет SDK 4.2 для RMS использует вашу реализацию обратного вызова, если маркер доступа не указан, требует обновления или срок его действия истек.

Библиотеки, используемые для аутентификации

Для реализации обратного вызова аутентификации необходимо скачать соответствующую библиотеку и настроить среду разработки для ее использования. Библиотеки ADAL для указанных ниже платформ можно найти на веб-сайте GitHub.

Ниже приведен список библиотек со ссылками на ресурсы, которые содержат рекомендации по настройке среды и использованию библиотеки.

Примечание

Мы рекомендуем использовать одну из библиотек ADAL, однако вы можете использовать и другие библиотеки проверки подлинности.

Параметры проверки подлинности

Чтобы выполнить проверку подлинности пользователя с использованием Azure RMS (или AD RMS), ADAL требуется несколько параметров. Это параметры стандартного протокола OAuth 2.0, которые обычно требуются для любого приложения Azure AD. Инструкции по использованию ADAL можно найти в файле README в соответствующих репозиториях Github, указанных выше.

  • Центр — это URL-адрес конечной точки аутентификации, как правило, AAD и ADFS.
  • Ресурс — это URL-адрес или URI приложения службы, к которому нужно получить доступ, как правило, Azure RMS или AD RMS.
  • Идентификатор пользователя — это имя участника-пользователя, как правило, электронный адрес пользователя, которому нужен доступ к приложению. Этот параметр можно не указывать, если пользователь еще не известен. Кроме того, он используется для кэширования маркера пользователя и запроса маркера из кэша. Кроме того, он часто используется в качестве указания при отображении запросов для пользователя.
  • Идентификатор клиента — это идентификатор клиентского приложения. Это должен быть допустимый идентификатор приложения Azure AD. Он поступает из предыдущего шага регистрации через портал Azure.
  • URI перенаправления — целевой URI для кода аутентификации, предоставляемый библиотеке аутентификации. Для iOS и Android требуются конкретные форматы. Они описаны в файлах README из соответствующих репозиториев GitHub для ADAL. Это значение поступает из предыдущего шага регистрации через портал Azure.

Примечание

Область. Параметр "Область" сейчас не используется; он зарезервирован для использования в будущем.

Android: msauth://packagename/Base64UrlencodedSignature

iOS: <app-scheme>://<bundle-id>

Примечание

Если вы не следуете этим инструкциям при написании кода приложения, рабочие процессы Azure RMS и Azure AD, скорее всего, завершатся с ошибкой и не будут поддерживаться Microsoft.com. Кроме того, если в рабочем приложении используется недопустимый идентификатор клиента, это может считаться нарушением лицензионного соглашения об управлении правами (RMLA).

Как выглядит выполнение обратного вызова аутентификации

Примеры кода аутентификации. Этот пакет SDK содержит пример кода, который показывает использование обратных вызовов аутентификации. Для удобства примеры кода представлены не только здесь, но и во всех указанных связанных разделах.

Аутентификация пользователя для Android. Дополнительные сведения см. в статье с примерами кода Android в описании шага 2 первого сценария, "Использование защищенного файла служб RMS".

    class MsipcAuthenticationCallback implements AuthenticationRequestCallback
    {
    ...

    @Override
    public void getToken(Map<String, String> authenticationParametersMap,
                         final AuthenticationCompletionCallback authenticationCompletionCallbackToMsipc)
    {
        String authority = authenticationParametersMap.get("oauth2.authority");
        String resource = authenticationParametersMap.get("oauth2.resource");
        String userId = authenticationParametersMap.get("userId");
        mClientId = "12345678-ABCD-ABCD-ABCD-ABCDEFGH12"; // get your registered Azure AD application ID here
        mRedirectUri = "urn:ietf:wg:oauth:2.0:oob";
        final String userHint = (userId == null)? "" : userId;
        AuthenticationContext authenticationContext = App.getInstance().getAuthenticationContext();
        if (authenticationContext == null || !authenticationContext.getAuthority().equalsIgnoreCase(authority))
        {
            try
            {
                authenticationContext = new AuthenticationContext(App.getInstance().getApplicationContext(), authority, …);
                App.getInstance().setAuthenticationContext(authenticationContext);
            }
            catch (NoSuchAlgorithmException e)
            {
                …
                authenticationCompletionCallbackToMsipc.onFailure();
            }
            catch (NoSuchPaddingException e)
            {
                …
                authenticationCompletionCallbackToMsipc.onFailure();
            }
       }
        App.getInstance().getAuthenticationContext().acquireToken(mParentActivity, resource, mClientId, mRedirectURI, userId, mPromptBehavior,
                       "&USERNAME=" + userHint, new AuthenticationCallback<AuthenticationResult>()
                        {
                            @Override
                            public void onError(Exception exc)
                            {
                                …
                                if (exc instanceof AuthenticationCancelError)
                                {
                                     …
                                    authenticationCompletionCallbackToMsipc.onCancel();
                                }
                                else
                                {
                                     …
                                    authenticationCompletionCallbackToMsipc.onFailure();
                                }
                            }

                            @Override
                            public void onSuccess(AuthenticationResult result)
                            {
                                …
                                if (result == null || result.getAccessToken() == null
                                        || result.getAccessToken().isEmpty())
                                {
                                     …
                                }
                                else
                                {
                                    // request is successful
                                    …
                                    authenticationCompletionCallbackToMsipc.onSuccess(result.getAccessToken());
                                }
                            }
                        });
                         }

Проверка подлинности пользователей в iOS/OS X — дополнительные сведения см. в примерах кода для iOS/OS X, в шаге 2 первого сценария, "Consuming an RMS protected file" (Использование файла, защищенного RMS).

    // AuthenticationCallback holds the necessary information to retrieve an access token.
    @interface MsipcAuthenticationCallback : NSObject<MSAuthenticationCallback>

    @end

    @implementation MsipcAuthenticationCallback

    - (void)accessTokenWithAuthenticationParameters:
         (MSAuthenticationParameters *)authenticationParameters
                                completionBlock:
         (void(^)(NSString *accessToken, NSError *error))completionBlock
    {
    ADAuthenticationError *error;
    ADAuthenticationContext* context = [ADAuthenticationContext authenticationContextWithAuthority:authenticationParameters.authority error:&error];

    NSString *appClientId = @"12345678-ABCD-ABCD-ABCD-ABCDEFGH12";

    // get your registered Azure AD application ID here

    NSURL *redirectURI = [NSURL URLWithString:@"ms-sample://com.microsoft.sampleapp"];

    // get your <app-scheme>://<bundle-id> here
    // Retrieve token using ADAL
    [context acquireTokenWithResource:authenticationParameters.resource
                             clientId:appClientId
                          redirectUri:redirectURI
                               userId:authenticationParameters.userId
                      completionBlock:^(ADAuthenticationResult *result)
                      {
                          if (result.status != AD_SUCCEEDED)
                          {
                              NSLog(@"Auth Failed");
                              completionBlock(nil, result.error);
                          }
                          else
                          {
                              completionBlock(result.accessToken, result.error);
                          }
                      }

        ];
    }

Проверка подлинности пользователей в Linux — дополнительные сведения см. в примерах кода для Linux.

    // Class Header
    class AuthCallback : public IAuthenticationCallback {
    private:

      std::shared_ptr<rmsauth::FileCache> FileCachePtr;
      std::string clientId_;
      std::string redirectUrl_;

      public:

      AuthCallback(const std::string& clientId,
               const std::string& redirectUrl);
      virtual std::string GetToken(shared_ptr<AuthenticationParameters>& ap) override;
    };

    class ConsentCallback : public IConsentCallback {
      public:

      virtual ConsentList Consents(ConsentList& consents) override;
    };

    // Class Implementation
    AuthCallback::AuthCallback(const string& clientId, const string& redirectUrl)
    : clientId_(clientId), redirectUrl_(redirectUrl) {
      FileCachePtr = std::make_shared<FileCache>();
    }

    string AuthCallback::GetToken(shared_ptr<AuthenticationParameters>& ap)
    {
      string redirect =
      ap->Scope().empty() ? redirectUrl_ : ap->Scope();

      try
      {
        if (redirect.empty()) {
        throw rmscore::exceptions::RMSInvalidArgumentException(
              "redirect Url is empty");
      }

      if (clientId_.empty()) {
      throw rmscore::exceptions::RMSInvalidArgumentException("client Id is empty");
      }

      AuthenticationContext authContext(
        ap->Authority(), AuthorityValidationType::False, FileCachePtr);

      auto result = authContext.acquireToken(ap->Resource(),
                                           clientId_, redirect,
                                           PromptBehavior::Auto,
                                           ap->UserId());
      return result->accessToken();
      }

      catch (const rmsauth::Exception& ex)
      {
        // out logs
        throw;
      }
    }