Во-первых, большое спасибо Крису Риснеру за помощь в этом решении! Крис является частью команды Corp DPE и проводит большую работу с мобильными службами Windows Azure (WAMS), включая этот сеанс в // build , который был отличным ресурсом для начала работы.
Если вы ознакомитесь с демонстрацией начала работы с WAMS по созданию TodoList , идея заключается в том, что данные в списке задач будут заблокированы для каждого пользователя. Одна из приятных особенностей WAMS заключается в том, что это легко реализовать с помощью javascript на стороне сервера… например , чтобы гарантировать, что возвращаются только строки текущего пользователя, можно использовать следующий скрипт чтения, который заставляет возвращаемые строки принадлежать только текущему пользователю. :
function read(query, user, request) { query.where({ userId: user.userId }); request.execute(); }
Если мы взломаем базу данных, то увидим, что userId является идентификатором, как показано ниже для учетной записи Microsoft:
MicrosoftAccount: 0123456789abcd
Когда приложение подключается к WAMS, возвращаемые данные включают в себя userId… например, если мы посмотрим на JSON в fiddler:
Приложение никогда не отображает эту информацию, и она запрашивается через SSL, но это важный фактор, и вот почему. Что если у нас есть полуоткрытые данные? В следующей версии Dark Skies я позволю пользователям прикреплять любимые места на карте. У пользователя есть возможность сделать эти точки общедоступными или сохранить их конфиденциальность … например, они могут указать отличное место для наблюдения за звездами и хотят поделиться им со всем миром:
… Или, возможно, пользователь прикрепляет свои домашние местоположения или частную ферму, которую он имеет право использовать, где это может быть неприемлемо для публичного показа.
Теперь возникает проблема: если местоположение является общедоступным, этот идентификатор пользователя включается в результаты JSON. Допустим, я запускаю приложение и вижу 10 публичных пинов. Если я посмотрю JSON в fiddler, я увижу userId для каждого из этих общедоступных контактов — например:
Теперь userId не содержит никакой личной информации. Это большое дело, тогда? Это не так, как если бы это было имя пользователя или адрес, и он был бы включен только в те места, которыми пользователь все равно делится публично.
Но если хакер когда-либо найдет способ сопоставить идентификатор пользователя с конкретным человеком, это проблема безопасности. Даже мое приложение не знает, кто на самом деле пользователи, оно просто знает идентификатор. Тем не менее, я думаю, с точки зрения наилучшей практики / моделирования угроз, если мы можем очистить эти данные, мы должны. Примечание: эта проблема не существует с примером списка задач, потому что пользователь только и всегда видит свои собственные данные.
В идеале мы хотели бы вернуть userId, если это текущий userId пользователя. Если точка принадлежит другому пользователю, мы должны удалить ее из набора результатов. Чтобы сделать это через скрипт чтения в WAMS, мы могли бы сделать что-то вроде:
function read(query, user, request) { request.execute( { success: function(results) { //scrub user token if (results.length > 0) { for (var i=0; i< results.length; i++) { if (results[i].UserId != user.userId) { results[i].UserId = 'scrubbeduser'; } } } request.respond(); } }); }
Если мы посмотрим на результаты в fiddler, то увидим, что я получу свой userId для любой из моих точек, но userId удаляется, если это точки другого пользователя, которые публикуются публично:
[Примечание: эти места являются случайными точками на карте для тестирования.]
Это хорошая практика. База данных, конечно, содержит правильную информацию, но данные о публичных точках гарантированно будут анонимными, если уязвимость когда-либо появится. Недостатком этого подхода являются дополнительные накладные расходы, поскольку мы повторяем результаты, но это довольно незначительно, учитывая относительно небольшие объемы данных.
Технический момент: в моей базе данных и классах я использую регистр Pascal (в порядке предпочтения), как вы можете видеть на приведенных выше снимках фиддлера, таких как UserId. В примере todo и в переменных javascript объекты обычно имеют дело с верблюдами. Итак, если вы используете какой-либо код здесь, просто имейте в виду, что дело имеет значение в таких ситуациях:
if (results[i].UserId != user.userId) // watch casing!
Убедитесь, что они соответствуют вашему соглашению. Так как регистр Pascal является стандартом для свойств в C #, а регистр верблюдов является стандартом в javascript, свойства в .NET могут быть украшены атрибутом datamember, чтобы сделать их согласованными в обоих местах — что я предпочитаю, как предпочтение не делать:
[DataMember(Name = "userId")] public string UserId { get; set; }