Предоставление входа в систему Google в приложении Metro, избегая повторных разрешений (Oauth2/Google OpenID)

У меня следующая ситуация:

В настоящее время я пытаюсь написать приложение в стиле Metro, позволяющее пользователю входить в свою учетную запись Google, а приложение запрашивает несколько разрешений, таких как Userinfo.profile и Userinfo.email.

Для этого я в настоящее время использую OAuthv2, и запрос подробностей сработал нормально (после некоторых усилий и исследований).

Используемый URL:

const string url = "https://accounts.google.com/o/oauth2/auth?" +
                   "client_id=" + clientId +
                   "&redirect_uri=" + "urn:ietf:wg:oauth:2.0:oob" +
                   "&response_type=code" +
                   "&scope=https://www.googleapis.com/auth/userinfo.profile+https://www.googleapis.com/auth/userinfo.email" +
                   "&access_type=offline";

Теперь проблема в том, что если я хочу, чтобы пользователь оставался аутентифицированным, мне нужно было либо сохранить токен на стороне клиента пользователем, либо найти какой-то способ войти в систему с помощью Google, сохранить сеанс и проверить, если он аутентифицирован.

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

Что я хочу сделать, так это то, что если пользователь входит в систему, у меня есть способ идентифицировать его и не всегда возлагать на него бремя, повторно запрашивая разрешения для данных деталей.

Я просмотрел OpenID, но всегда получаю

<?xml version="1.0" encoding="UTF-8"?>
<xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)">
<XRD>
<Service priority="0">
<Type>http://specs.openid.net/auth/2.0/server</Type>
<Type>http://openid.net/srv/ax/1.0</Type>
<Type>http://specs.openid.net/extensions/ui/1.0/mode/popup</Type>
<Type>http://specs.openid.net/extensions/ui/1.0/icon</Type>
<Type>http://specs.openid.net/extensions/pape/1.0</Type>
<URI>https://www.google.com/accounts/o8/ud</URI>
</Service>
</XRD>
</xrds:XRDS>

В ответ на этот URL:

https://www.google.com/accounts/o8/id?openid.mode=checkid_setup&openid.ns=http://specs.openid.net/auth/2.0&openid.return_to=urn:ietf:wg:oauth:2.0:oob&openid.ns.ui=http://specs.openid.net/extensions/ui/1.0&openid.ns.ax=http://openid.net/srv/ax/1.0&openid.ax.mode=fetch_request&openid.ax.required=email,firstname,language,lastname,country&openid.ns.ext=http://specs.openid.net/extensions/oauth/1.0&openid.ext2.consumer=https://www.google.com/accounts/o8/ud?openid.mode=checkid_setup&openid.ns=http://specs.openid.net/auth/2.0&openid.return_to=urn:ietf:wg:oauth:2.0:oob&openid.ext2.scope=https://www.googleapis.com/auth/userinfo.profile+https://www.googleapis.com/auth/userinfo.email

Я неправильно строю?

Если есть какие-либо предложения о том, как выполнить это «правильно», чего я пытаюсь достичь (интеграция с Google, разрешение пользователю входить в систему с использованием электронной почты Google и только если он не авторизовал приложение, попросите его сделать это, а также узнайте, кто он такой при входе в систему во второй+ раз), или как я могу это сделать, пожалуйста не стесняйтесь.

Кроме того, используя урезанную версию платформы .Net 4.5, похоже, я не могу использовать библиотеки OpenID, поскольку они полагаются на полную версию 4.5.

*Изменить* Просмотр MSDN появляется:

To support SSO, the online provider must allow you to register a redirect URI in the form ms-app://appSID, where appSID is the SID for your app. 

Значит ли это, что это просто невозможно? Потому что в Google я могу запросить ключ только для домена с http(s)://?


person Daneo    schedule 17.12.2012    source источник


Ответы (1)


Вы смотрели на это? https://developers.google.com/accounts/docs/OAuth2Login

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

Ваше приложение должно отслеживать, есть ли у вас действительный токен обновления для конкретного пользователя. Затем используйте этот токен, чтобы получить текущие учетные данные. Вы можете использовать tokeninfo enpoint для проверки токена. Если у вас есть действительный токен для пользователя, нет необходимости отправлять его через поток кода, чтобы получить еще один токен обновления.

Если вы используете конечную точку tokeninfo, поле userid присутствует только в том случае, если https://www.googleapis.com/auth/userinfo.profile присутствовала в запросе токена доступа. Значение этого поля является неизменяемым идентификатором вошедшего в систему пользователя. Сохраните это, и у вас должен быть надежный идентификатор пользователя.

person David Primmer    schedule 18.12.2012
comment
Да, у меня есть, и я действительно получаю токен авторизации, обмениваю его на токен доступа и т. д. Это работает нормально, но что, если пользователь выходит из приложения, на какой URL-адрес Google я должен перенаправить их для получения их соответствующего идентификатора, чтобы я мог понять, какой токен использовать? Что-то вроде страницы, где пользователь входит в систему, и я получаю его userId, поэтому я знаю, какой токен использовать? Все этой авторизации работают нормально. - person Daneo; 18.12.2012
comment
Для установленных приложений у нас в настоящее время нет способа отправить пользователя нам без запроса. Это возможно для клиентских приложений js, но мы запрещаем это для установленных приложений по соображениям безопасности. Пользователь должен выходить из вашего приложения очень редко, например, если он хочет переключить учетную запись. Вы можете оставить их в системе навсегда и просто позволить им добавлять учетные записи и переключаться. - person David Primmer; 18.12.2012
comment
Я вижу, и в качестве побочного вопроса (возможно, обновите свой ответ этим и частью соображений безопасности), где должны храниться clientSecret и Id? Потому что, если приложение дизассемблировано, они могут просто посмотреть на секрет, так что мне делать в этом случае? Или это не имеет большого значения? - person Daneo; 19.12.2012
comment
Установленные приложения не имеют настоящих секретов по указанной вами причине. Ваша лучшая надежда, если кто-то украдет ваш идентификатор клиента и израсходует вашу квоту, - это изменить идентификаторы клиентов. Если ваше установленное приложение находится на Android, вы должны использовать сервисы Google Play, а не установленный поток приложений. - person David Primmer; 21.12.2012
comment
Хорошо, полезно знать. Так что было бы лучше сохранить это где-то еще и получить его в другом месте, возможно, используя какой-то веб-сервис. - person Daneo; 21.12.2012