Как защитить интеллектуальную собственность моего приложения на Autodesk Exchange - часть 3
В предыдущем посте я показал, как проверить права пользователя из веб-службы с новым API для проверки прав, он может быть также применен к настольным приложением. В этой статье я расскажу, как это сделать в основе плагина AutoCAD. С новым API мы можем проверить, имеет ли пользователь право использовать это приложение, что означает, что мы можем проверить заплатил ли он на Autodesk Exchange, чтобы загрузить это приложение, а не скопировал его откуда-то. Как мы уже говорили в предыдущей записи, этому API необходимы два параметра, один - это ваш AppId. Вы можете получить свой AppId с вашей стартовой страницы приложения на Exchange, и вам, возможно, потребуется URL-декодировать с помощью таких инструментов, как этот.
Другим параметром является внутренней Autodesk ID для AutoCAD, вы можете использовать недокументированные системные переменные - ONLINEUSERID, но в этой статье я представлю стандартный способ - получение внутреннего идентификатора пользователя с OAuth.Мы уже опубликовал несколько примеров OAuth на GitHub , пожалуйста, ознакомьтесь с ними, если вы не знакомы с OAuth.
Мой пример приложения является надстройкой AutoCAD, которую пользователь запускает при помощи команды "StartMyApp". Конечно, Вы можете создать хороший пользовательский интерфейс с лентой, я же для демонстрации использую самый простой способ.
- [CommandMethod("MyAppGroup", "StartMyApp", "StartMyApp", CommandFlags.Modal)]
- public void MyCommand() // Этот метод может иметь любое имя
- {
- Autodesk.AutoCAD.ApplicationServices.Application
- .ShowModelessWindow(new myAppWin());
- }
Когда моё пользовательское окно запустится, я прошу пользователя войти в систему со своим Autodesk ID, для проверки того, есть ли у него право на использование моего приложения. Если проверка пройдена, "настоящая" функциональная кнопка доступна, в противном случае, я предлагаю ему купить это приложение на Autodesk Exchange.
Итак, давайте напишем код, вот фрагмент программы, прочитайте комментарии:
- // Жестко указанный заказчик, секретные ключи и базовый URL-адрес.
- // В реальном мире приложений, эти значения должны скрытыми.
- // Один из подходов заключается в шифровании и/или закрытии этих значений
- private const string m_ConsumerKey = "ваш ключ заказчика";
- private const string m_ConsumerSecret = "ваш секрет заказчика";
- private const string m_baseURL = https://accounts.autodesk.com;
- private const string AUTODESK_EXCHANGE_URL = "https://apps.exchange.autodesk.com";
- private const string CHECK_ENTITLEMENT_ENDPOINT
- = "webservices/checkentitlement";
- private static RestClient m_Client;
- private string m_oAuthReqToken;
- private string m_oAuthReqTokenSecret;
- private string m_strPIN;
- private string m_oAuthAccessToken;
- private string m_oAuthAccessTokenSecret;
- private string m_sessionHandle;
- public myAppWin()
- {
- InitializeComponent();
- }
- private void Button_Click(object sender, RoutedEventArgs e)
- {
- string internalUserId = GetUserIdWithOAuth();
- if (internalUserId == string.Empty)
- {
- logOutput.Text = "Вы не имеете прав использовать это приложение"
- +"пожалуйста, приобретите его в Autodesk Exchange.";
- return;
- }
- // Так как вы, вероятно, не знаете этот AppId, пока вы его не опубликуете приложение,
- // давайте сохраним AppId в конфигурационном файле, чтобы иметь возможность отредактировать впоследствии
- // без изменения исходного кода
- // Читаем этот APPID из файла конфигурации
- string thisAppId = ConfigReader.ReadConfig("thisAppId");
- bool hasEntitilement = CheckEntitlement(internalUserId, thisAppId);
- if (hasEntitilement)
- {
- logOutput.Text = "Вы имеете право использовать это приложение.Благодарим Вас за покупку! ";
- btnDoMyWork.IsEnabled = true;
- }
- else
- {
- logOutput.Text = "Вы не имеете права использовать это приложение."
- + "Пожалуйста, приобретите приложение на Autodesk Exchange.";
- }
- }
- private string GetUserIdWithOAuth()
- {
- // Создание объектов RestSharp библиотеки RestClient. RestSharp является бесплатным и делает
- // очень легким создание приложений, которые используют OAuth и OpenID протоколы с поставщиком, который поддерживает
- // эти протоколы
- m_Client = new RestClient(m_baseURL);
- m_Client.Authenticator =
- OAuth1Authenticator.ForRequestToken(m_ConsumerKey, m_ConsumerSecret);
- // Строит HTTP-запрос для маркера запроса и выполняет его на провайдере OAuth
- var request = new RestRequest("OAuth/RequestToken", Method.POST);
- var response = m_Client.Execute(request);
- if (response.StatusCode != HttpStatusCode.OK)
- {
- m_Client = null;
- logOutput.Text = "не могу запросить маркер из от поставщика Autodesk oxygen";
- return string.Empty;
- }
- // HTTP-запрос удался. Получаем маркер запроса и связанные параметры.
- var qs = HttpUtility.ParseQueryString(response.Content);
- m_oAuthReqToken = qs["oauth_token"];
- m_oAuthReqTokenSecret = qs["oauth_token_secret"];
- var oauth_callback_confirmed = qs["oauth_callback_confirmed"];
- var x_oauth_client_identifier = qs["x_oauth_client_identifier"];
- var xoauth_problem = qs["xoauth_problem"];
- var oauth_error_message = qs["oauth_error_message"];
- // Цикл в секции установки URL авторизации для HTTP-запроса авторизации
- RestRequest authorizeRequest = new RestRequest
- {
- Resource = "OAuth/Authorize",
- };
- authorizeRequest.AddParameter("viewmode", "desktop");
- authorizeRequest.AddParameter("oauth_token", m_oAuthReqToken);
- Uri authorizeUri = m_Client.BuildUri(authorizeRequest);
- // Запуск другого окна с элментом управления браузера и переход по URL Авторизации
- BrowserAuthenticate frm = new BrowserAuthenticate();
- frm.Uri = authorizeUri;
- if (frm.ShowDialog() != true)
- {
- m_Client = null;
- logOutput.Text = "В группе удалось не выполнить авторизацию";
- return string.Empty;
- }
- // Постройка HTTP-запроса на маркер доступа
- request = new RestRequest("OAuth/AccessToken", Method.POST);
- m_Client.Authenticator = OAuth1Authenticator.ForAccessToken(
- m_ConsumerKey, m_ConsumerSecret, m_oAuthReqToken, m_oAuthReqTokenSecret
- );
- // Выполняем маркера запроса доступа
- response = m_Client.Execute(request);
- if (response.StatusCode != HttpStatusCode.OK)
- {
- m_Client = null;
- logOutput.Text = "Не можем получить маркер доступа с Вашего счета Autodesk";
- return string.Empty;
- }
- // Запрос маркера доступа успешен. Разбираем ответа и храним маркер, секретный ключ маркера, и указатель на сессию
- qs = HttpUtility.ParseQueryString(response.Content);
- m_oAuthAccessToken = qs["oauth_token"];
- m_oAuthAccessTokenSecret = qs["oauth_token_secret"];
- var x_oauth_user_name = qs["x_oauth_user_name"];
- var x_oauth_user_guid = qs["x_oauth_user_guid"];
- return x_oauth_user_guid;
- }
- /// <summary>
- /// Проверяем, имеет ли пользователь право на использование приложения
- /// </summary>
- /// <param name="internalUserId"></param>
- /// <param name="thisAppId"></param>
- /// <returns></returns>
- private bool CheckEntitlement(string internalUserId, string thisAppId)
- {
- RestClient client = new RestClient(AUTODESK_EXCHANGE_URL);
- RestRequest req = new RestRequest(CHECK_ENTITLEMENT_ENDPOINT);
- req.Method = Method.GET;
- req.AddParameter("userid", internalUserId);
- req.AddParameter("appid", thisAppId);
- ServicePointManager.ServerCertificateValidationCallback
- += (sender, certificate, chain, sslPolicyErrors) => true;
- IRestResponse<EntitlementResult> resp = client.Execute<EntitlementResult>(req);
- if (resp.Data != null && resp.Data.IsValid)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- class EntitlementResult
- {
- public string UserId { get; set; }
- public string AppId { get; set; }
- public bool IsValid { get; set; }
- public string Message { get; set; }
- }
Довольно просто, не так ли? Вы можете найти полный исходный код на GitHub , надеюсь, вам будет полезно.
Автор перевода: Daniel Du
Обсуждение: http://adn-cis.org/forum/index.php?topic=1877
Опубликовано 18.02.2015