ADN Open CIS
Сообщество программистов Autodesk в СНГ

18/02/2015

Как защитить интеллектуальную собственность моего приложения на Autodesk Exchange - часть 3

В предыдущем посте я показал, как проверить права пользователя из веб-службы с новым API для проверки прав, он может быть также применен к настольным приложением. В этой статье я расскажу, как это сделать в основе плагина AutoCAD. С новым API мы можем проверить, имеет ли пользователь право использовать это приложение, что означает, что мы можем проверить заплатил ли он на Autodesk Exchange, чтобы загрузить это приложение, а не скопировал его откуда-то. Как мы уже говорили в   предыдущей записи, этому API необходимы два параметра, один - это ваш AppId. Вы можете получить свой AppId с вашей стартовой страницы приложения на Exchange, и вам, возможно, потребуется URL-декодировать с помощью таких инструментов, как этот.

Другим параметром является внутренней Autodesk ID для AutoCAD, вы можете использовать недокументированные системные переменные - ONLINEUSERID, но в этой статье я представлю стандартный способ - получение внутреннего идентификатора пользователя с OAuth.Мы уже опубликовал несколько   примеров OAuth на GitHub , пожалуйста, ознакомьтесь с ними, если вы не знакомы с OAuth.

Мой пример приложения является надстройкой AutoCAD, которую пользователь запускает при помощи команды "StartMyApp". Конечно, Вы можете создать хороший пользовательский интерфейс с лентой, я же для демонстрации использую самый простой способ.

Код - C#: [Выделить]
  1. [CommandMethod("MyAppGroup", "StartMyApp", "StartMyApp", CommandFlags.Modal)]
  2. public void MyCommand() // Этот метод может иметь любое имя
  3. {
  4.     Autodesk.AutoCAD.ApplicationServices.Application
  5.              .ShowModelessWindow(new myAppWin());
  6. }

Когда моё пользовательское окно запустится, я прошу пользователя войти в систему со своим Autodesk ID, для проверки того, есть ли у него право на использование моего приложения. Если проверка пройдена, "настоящая" функциональная кнопка доступна, в противном случае, я предлагаю ему купить это приложение на Autodesk Exchange.

 

 

 

Итак, давайте напишем код, вот фрагмент программы, прочитайте комментарии:

Код - C#: [Выделить]
  1.         // Жестко указанный заказчик, секретные ключи и базовый URL-адрес.
  2.         // В реальном мире приложений, эти значения должны скрытыми.
  3.         // Один из подходов заключается в шифровании и/или закрытии этих значений
  4.         private const string m_ConsumerKey = "ваш ключ заказчика";
  5.         private const string m_ConsumerSecret = "ваш секрет заказчика";
  6.         private const string m_baseURL = https://accounts.autodesk.com;
  7.         private const string AUTODESK_EXCHANGE_URL = "https://apps.exchange.autodesk.com";
  8.         private const string CHECK_ENTITLEMENT_ENDPOINT
  9.                    = "webservices/checkentitlement";
  10.         private static RestClient m_Client;
  11.         private string m_oAuthReqToken;
  12.         private string m_oAuthReqTokenSecret;
  13.         private string m_strPIN;
  14.         private string m_oAuthAccessToken;
  15.         private string m_oAuthAccessTokenSecret;
  16.         private string m_sessionHandle;
  17.         public myAppWin()
  18.         {
  19.             InitializeComponent();
  20.         }
  21.         private void Button_Click(object sender, RoutedEventArgs e)
  22.         {
  23.             string internalUserId = GetUserIdWithOAuth();
  24.             if (internalUserId == string.Empty)
  25.             {
  26.                 logOutput.Text = "Вы не имеете прав использовать это приложение"
  27.                     +"пожалуйста, приобретите его в Autodesk Exchange.";
  28.                 return;
  29.             }
  30.             // Так как вы, вероятно, не знаете этот AppId, пока вы его не опубликуете приложение,
  31.             // давайте сохраним AppId в конфигурационном файле, чтобы иметь возможность отредактировать впоследствии
  32.             // без изменения исходного кода
  33.             // Читаем этот APPID из файла конфигурации
  34.             string thisAppId = ConfigReader.ReadConfig("thisAppId");
  35.             bool hasEntitilement = CheckEntitlement(internalUserId, thisAppId);
  36.             if (hasEntitilement)
  37.             {
  38.                 logOutput.Text = "Вы имеете право использовать это приложение.Благодарим Вас за покупку! ";
  39.                 btnDoMyWork.IsEnabled = true;
  40.             }
  41.             else
  42.             {
  43.                 logOutput.Text = "Вы не имеете права использовать это приложение."
  44.                     + "Пожалуйста, приобретите приложение на Autodesk Exchange.";
  45.             }
  46.         }
  47.         private string GetUserIdWithOAuth()
  48.         {
  49.             // Создание объектов RestSharp библиотеки RestClient. RestSharp является бесплатным и делает
  50.             // очень легким создание приложений, которые используют OAuth и OpenID протоколы с поставщиком, который поддерживает
  51.             // эти протоколы
  52.             m_Client = new RestClient(m_baseURL);
  53.             m_Client.Authenticator =
  54.           OAuth1Authenticator.ForRequestToken(m_ConsumerKey, m_ConsumerSecret);
  55.             // Строит HTTP-запрос для маркера запроса и выполняет его на провайдере OAuth
  56.             var request = new RestRequest("OAuth/RequestToken", Method.POST);
  57.             var response = m_Client.Execute(request);
  58.             if (response.StatusCode != HttpStatusCode.OK)
  59.             {
  60.                 m_Client = null;
  61.                 logOutput.Text = "не могу запросить маркер из от поставщика Autodesk oxygen";
  62.                 return string.Empty;
  63.             }
  64. // HTTP-запрос удался. Получаем маркер запроса и связанные параметры.
  65.             var qs = HttpUtility.ParseQueryString(response.Content);
  66.             m_oAuthReqToken = qs["oauth_token"];
  67.             m_oAuthReqTokenSecret = qs["oauth_token_secret"];
  68.             var oauth_callback_confirmed = qs["oauth_callback_confirmed"];
  69.             var x_oauth_client_identifier = qs["x_oauth_client_identifier"];
  70.             var xoauth_problem = qs["xoauth_problem"];
  71.             var oauth_error_message = qs["oauth_error_message"];
  72.             // Цикл в секции установки URL авторизации для HTTP-запроса авторизации
  73.             RestRequest authorizeRequest = new RestRequest
  74.             {
  75.                 Resource = "OAuth/Authorize",
  76.             };
  77.             authorizeRequest.AddParameter("viewmode", "desktop");
  78.             authorizeRequest.AddParameter("oauth_token", m_oAuthReqToken);
  79.             Uri authorizeUri = m_Client.BuildUri(authorizeRequest);
  80.             // Запуск другого окна с элментом управления браузера и переход по URL Авторизации
  81.             BrowserAuthenticate frm = new BrowserAuthenticate();
  82.             frm.Uri = authorizeUri;
  83.             if (frm.ShowDialog() != true)
  84.             {
  85.                 m_Client = null;
  86.                 logOutput.Text = "В группе удалось не выполнить авторизацию";
  87.                 return string.Empty;
  88.             }
  89.             // Постройка HTTP-запроса на маркер доступа
  90.             request = new RestRequest("OAuth/AccessToken", Method.POST);
  91.             m_Client.Authenticator = OAuth1Authenticator.ForAccessToken(
  92.            m_ConsumerKey, m_ConsumerSecret, m_oAuthReqToken, m_oAuthReqTokenSecret
  93.            );
  94.             // Выполняем маркера запроса доступа
  95.             response = m_Client.Execute(request);
  96.             if (response.StatusCode != HttpStatusCode.OK)
  97.             {
  98.                 m_Client = null;
  99.                 logOutput.Text = "Не можем получить маркер доступа с Вашего счета Autodesk";
  100.                 return string.Empty;
  101.             }
  102.             // Запрос маркера доступа успешен. Разбираем ответа и храним маркер, секретный ключ маркера, и указатель на сессию
  103.             qs = HttpUtility.ParseQueryString(response.Content);
  104.             m_oAuthAccessToken = qs["oauth_token"];
  105.             m_oAuthAccessTokenSecret = qs["oauth_token_secret"];
  106.             var x_oauth_user_name = qs["x_oauth_user_name"];
  107.             var x_oauth_user_guid = qs["x_oauth_user_guid"];
  108.  
  109.             return x_oauth_user_guid;
  110.         }
  111.         /// <summary>
  112.         /// Проверяем, имеет ли пользователь право на использование приложения
  113.         /// </summary>
  114.         /// <param name="internalUserId"></param>
  115.         /// <param name="thisAppId"></param>
  116.         /// <returns></returns>
  117.         private bool CheckEntitlement(string internalUserId, string thisAppId)
  118.         {
  119.             RestClient client = new RestClient(AUTODESK_EXCHANGE_URL);
  120.             RestRequest req = new RestRequest(CHECK_ENTITLEMENT_ENDPOINT);
  121.             req.Method = Method.GET;
  122.             req.AddParameter("userid", internalUserId);
  123.             req.AddParameter("appid", thisAppId);
  124.          
  125.             ServicePointManager.ServerCertificateValidationCallback
  126.                 += (sender, certificate, chain, sslPolicyErrors) => true;
  127.             IRestResponse<EntitlementResult> resp = client.Execute<EntitlementResult>(req);
  128.             if (resp.Data != null && resp.Data.IsValid)
  129.             {
  130.                 return true;
  131.             }
  132.             else
  133.             {
  134.                 return false;
  135.             }
  136.         }
  137.     class EntitlementResult
  138.     {
  139.         public string UserId { get; set; }
  140.         public string AppId { get; set; }
  141.         public bool IsValid { get; set; }
  142.         public string Message { get; set; }
  143.     }

 

Довольно просто, не так ли? Вы можете найти полный исходный код на GitHub , надеюсь, вам будет полезно.

Источник: http://adndevblog.typepad.com/cloud_and_mobile/2014/05/how-to-protect-my-intellectual-property-of-my-app-on-autodesk-exchange-part-3.html

Автор: Daniel Du
Автор перевода: Daniel Du

Обсуждение: http://adn-cis.org/forum/index.php?topic=1877

Опубликовано 18.02.2015