Подтвердить что ты не робот

Получить дополнительные данные из структуры MVC5. Поставщик идентификации OAuth/OWin с внешним поставщиком авторизации

Я пытаюсь использовать новую среду MVC5 в предварительном просмотре VS 2013.

Структура проверки подлинности членства была пересмотрена и заменена на OWin.

В частности, я включил внешний аутентификатор Google auth.

Это было очень просто сделать.

Просто раскомментируйте эту строку: app.UseGoogleAuthentication(); в файле Startup.Auth.cs в каталоге App_Start нового проекта MVC по умолчанию.

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

В рамках более старой реализации OAuth против провайдера членства asp.net был способ зафиксировать это с помощью этого словаря ExtraData, найденного здесь: ProviderDetail.ExtraData Свойство.

Я не могу найти много документации о том, как OAuth и OWin работают вместе и как получить доступ к этим дополнительным данным.

Может кто-нибудь просветить меня?

4b9b3361

Ответ 1

Недавно мне также нужно было получить доступ к картине профиля Google, и вот как я ее решаю...

Если вы просто включите код app.UseGoogleAuthentication(); в файле Startup.Auth.cs, этого недостаточно, потому что в этом случае Google вообще не возвращает никакой информации о картине профиля (или я не понял, как получить она).

Вам действительно нужно использовать интеграцию OAuth2 вместо Open ID, которая включена по умолчанию. И вот как я это сделал...

Прежде всего, вам необходимо зарегистрировать свое приложение на стороне Google и получить "Идентификатор клиента" и "Клиентский секрет". Как только это будет сделано, вы сможете пойти дальше (это понадобится вам позже). Подробная информация, как это сделать здесь.

Замените app.UseGoogleAuthentication(); на

    var googleOAuth2AuthenticationOptions = new GoogleOAuth2AuthenticationOptions
    {
        ClientId = "<<CLIENT ID FROM GOOGLE>>",
        ClientSecret = "<<CLIENT SECRET FROM GOOGLE>>",
        CallbackPath = new PathString("/Account/ExternalGoogleLoginCallback"),
        Provider = new GoogleOAuth2AuthenticationProvider() {
            OnAuthenticated = async context =>
            {
                context.Identity.AddClaim(new Claim("picture", context.User.GetValue("picture").ToString()));
                context.Identity.AddClaim(new Claim("profile", context.User.GetValue("profile").ToString()));
            }
        }
    };

    googleOAuth2AuthenticationOptions.Scope.Add("email");

    app.UseGoogleAuthentication(googleOAuth2AuthenticationOptions);

После этого вы можете использовать код для доступа к URL-адресу изображения профиля так же, как и для любых других свойств

var externalIdentity = HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
var pictureClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type.Equals("picture"));
var pictureUrl = pictureClaim.Value;

Ответ 2

С RTW-версией идентификатора asp.net следующий код в ExternalLoginCallback делает это для меня.

var externalIdentity = await HttpContext.GetOwinContext().Authentication
    .GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
var displayName = externalIdentity.Name;
var email = externalIdentity.FindFirstValue(ClaimTypes.Email);

Ответ 3

Используя ответ Alex Wheat, я придумал решение для поиска профиля google +, пола и электронной почты с помощью Google Authentication.

Startup.Auth.cs:

var googleOptions = new GoogleOAuth2AuthenticationOptions()
{
    ClientId = "<<client id - google>>",
    ClientSecret = "<<secret for your app>>",
    Provider = new GoogleOAuth2AuthenticationProvider()
    {
        OnAuthenticated = context =>
        {
            var userDetail = context.User;
            context.Identity.AddClaim(new Claim(ClaimTypes.Name,context.Identity.FindFirstValue(ClaimTypes.Name)));
            context.Identity.AddClaim(new Claim(ClaimTypes.Email,context.Identity.FindFirstValue(ClaimTypes.Email)));

            var gender = userDetail.Value<string>("gender");
            context.Identity.AddClaim(new Claim(ClaimTypes.Gender, gender));

            var picture = userDetail.Value<string>("picture");
            context.Identity.AddClaim(new Claim("picture", picture));

            return Task.FromResult(0);
        },
    },
};
googleOptions.Scope.Add("https://www.googleapis.com/auth/plus.login");
googleOptions.Scope.Add("https://www.googleapis.com/auth/userinfo.email");

app.UseGoogleAuthentication(googleOptions);

Чтобы получить доступ к расширенным данным профиля, вы должны добавить два запроса к запросу - plus.login и userinfo.email. Если вы добавите только область plus.login, вы не сможете увидеть электронное письмо пользователя. Если вы используете шаблон по умолчанию ASP.NET MVC5 для аутентификации, он будет показывать только адрес электронной почты пользователя, имя, фамилию и адрес google+. Используя приведенный здесь способ, вы также получите доступ к ссылке на изображение пользователя.

Свойство context.User переносит сериализацию JSON пользовательских данных, отправленных по проводу, и имеет полезные методы, позволяющие пользователю находить свойство по его ключу.

Чтобы узнать больше о концепции логинов, ознакомьтесь с: https://developers.google.com/+/api/oauth#login-scopes

Ответ 5

Следующие работы для меня для facebook:

StartupAuth.cs:

var facebookAuthenticationOptions = new FacebookAuthenticationOptions()
{
    AppId = "x",
    AppSecret = "y"
};
facebookAuthenticationOptions.Scope.Add("email");
app.UseFacebookAuthentication(facebookAuthenticationOptions);

Метод ExternalLoginCallback:

var externalIdentity = HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
var emailClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email);
var email = emailClaim.Value;

И для Google:

StartupAuth.cs

app.UseGoogleAuthentication();

Метод ExternalLoginCallback (тот же, что и для facebook):

var externalIdentity = HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
var emailClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email);
var email = emailClaim.Value;

Если я установил точку останова здесь:

var email = emailClaim.Value;

Я вижу адрес электронной почты для Facebook и Google в отладчике.

Обновить. Вместо этого см. это сообщение для правильного и полного решения; Получение электронной почты от внешних поставщиков Google и Facebook во время действия учетной записи в приложении MVC5 по умолчанию

Ответ 6

Так что, к сожалению, это не очень просто, один из способов сделать это - связать событие с подтверждением GoogleProvider Authenticated и добавить персонализированное требование к Identity Identity с аватаром:

public class MyGoogleProvider : GoogleAuthenticationProvider {
    public override Task Authenticated(GoogleAuthenticatedContext context) {
        context.Identity.AddClaim(new Claim("avatarClaim", "<fetch avatar url here>"));
        return base.Authenticated(context);
    }
}

app.UseGoogleAuthentication(new GoogleAuthenticationOptions() { Provider = new MyGoogleProvider() });

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

Ответ 7

Здесь - хороший ответ от AndrewPolland. Работайте со мной. Он использует новый токен доступа oauth для получения информации о пользователе после входа в систему. Отсюда Дипак Госвами объясняет, как использовать этот вызов api.