Используйте OpenIdConnectServer и попробуйте подключиться к Facebook через службу API.

Я пытаюсь найти способ сделать мой API способным связать пользователя из Facebook с моими пользователями Identity.

Контекст приложения

Я разрабатываю мобильное приложение (в Xamarin), которому необходимо войти в систему с помощью имени пользователя/пароля и Facebook. Я уже установил конфигурацию app.UseOpenIdConnectServer и создал пользовательскую Provider, поэтому мое приложение уже работает с именем пользователя/паролем.

Теперь я пытаюсь сделать эту интеграцию с Facebook и не могу найти способ добиться этого.

Я думал о создании службы в API, например /api/auth/login-facebook/, передающей access-token из Facebook, но мне нужно вернуть access-token моего приложения API в мобильное приложение, чтобы мобильное приложение могло вызывать все другие службы, которым требуется авторизация.

Любая помощь по этому поводу?

Визуальный способ того, что я пытаюсь получить:

  1. Пользователь нажимает «Войти через Facebook» в мобильном приложении.
  2. Мобильное приложение вызывает /api/auth/login-facebook/, передавая access-token из Facebook
  3. В приложении API я проверю access-token с пакетом Facebook
  4. Если пользователь не существует, я создам его с данными, которые мне вернул Facebook, и после этого я сгенерирую access-token, чтобы предоставить доступ к моему приложению API.
  5. Если пользователь существует, я сгенерирую access-token, чтобы предоставить доступ к моему приложению API.
  6. Верните access-token в мобильное приложение, чтобы оно могло вызывать другие службы.

Если мои знания неверны и я должен выполнить эту интеграцию/вход другим способом, пожалуйста, сообщите мне об этом!


person Raphael Furlan    schedule 18.08.2016    source источник


Ответы (1)


Процесс, который вы описываете, очень похож на "предоставление утверждений", процесс, который был стандартизирован в прошлом году. .

Чтобы использовать этот поток, вам обычно нужно получить стандартный токен от внешнего поставщика (например, утверждение JWT или SAML), чтобы ваш собственный сервер авторизации мог проверьте его и извлеките содержащиеся в нем утверждения. К сожалению, это не то, что вы можете сделать с Facebook или с большинством социальных сетей в целом.

Новый проект OAuth2, скорее всего, поможет изменить это в будущее, но, вероятно, потребуется некоторое время, прежде чем основные службы начнут его реализовывать.

Хорошей новостью является то, что ничто не мешает вам тем временем создать свой собственный тип гранта «Токен доступа к Facebook». Вот как вы можете реализовать грант утверждения с помощью ASOS beta6:

public override Task ValidateTokenRequest(ValidateTokenRequestContext context)
{
    // Reject the token request if it doesn't use grant_type=password, refresh_token
    // or urn:ietf:params:oauth:grant-type:facebook_access_token.
    if (!context.Request.IsPasswordGrantType() &&
        !context.Request.IsRefreshTokenGrantType() &&
         context.Request.GrantType != "urn:ietf:params:oauth:grant-type:facebook_access_token")
    {
        context.Reject(
            error: OpenIdConnectConstants.Errors.UnsupportedGrantType,
            description: "The specified grant type is not supported by this server.");

        return Task.FromResult(0);
    }

    // Reject the token request if the assertion parameter is missing.
    if (context.Request.GrantType == "urn:ietf:params:oauth:grant-type:facebook_access_token" &&
        string.IsNullOrEmpty(context.Request.Assertion))
    {
        context.Reject(
            error: OpenIdConnectConstants.Errors.InvalidRequest,
            description: "The assertion is missing.");

        return Task.FromResult(0);
    }

    // Since there's only one application and since it's a public client
    // (i.e a client that cannot keep its credentials private), call Skip()
    // to inform the server the request should be accepted without 
    // enforcing client authentication.
    context.Skip();

    return Task.FromResult(0);
}

public override Task HandleTokenRequest(HandleTokenRequestContext context)
{
    // Only handle grant_type=password and urn:ietf:params:oauth:grant-type:facebook_access_token
    // requests and let the OpenID Connect server middleware handle the refresh token requests.
    if (context.Request.IsPasswordGrantType())
    {
        // Skipped for brevity.
    }

    else if (context.Request.GrantType == "urn:ietf:params:oauth:grant-type:facebook_access_token")
    {
        // The assertion corresponds to the Facebook access token.
        var assertion = context.Request.Assertion;

        // Create a new ClaimsIdentity containing the claims that
        // will be used to create an id_token and/or an access token.
        var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme);

        // Validate the access token using Facebook's token validation
        // endpoint and add the user claims you retrieved here.
        identity.AddClaim(ClaimTypes.NameIdentifier, "FB user identifier");

        // Create a new authentication ticket holding the user identity.
        var ticket = new AuthenticationTicket(
            new ClaimsPrincipal(identity),
            new AuthenticationProperties(),
            OpenIdConnectServerDefaults.AuthenticationScheme);

        // Set the list of scopes granted to the client application.
        ticket.SetScopes(new[]
        {
            /* openid: */ OpenIdConnectConstants.Scopes.OpenId,
            /* email: */ OpenIdConnectConstants.Scopes.Email,
            /* profile: */ OpenIdConnectConstants.Scopes.Profile,
            /* offline_access: */ OpenIdConnectConstants.Scopes.OfflineAccess
        }.Intersect(context.Request.GetScopes()));

        context.Validate(ticket);
    }

    return Task.FromResult(0);
}

введите здесь описание изображения

person Kévin Chalet    schedule 18.08.2016
comment
@Pinpoint Отличный ответ, но как токен обновления появляется в этом конкретном потоке? Срок действия access_token, выданного Google, истекает, поэтому можно ли реализовать своего рода поток токенов обновления с помощью гранта Assertion? - person ; 13.12.2018
comment
@Ben, хотя мой снимок экрана этого не показывает, токен обновления действительно возвращается, если вы запрашиваете и предоставляете область offline_access. В этом случае вам не понадобится первоначальный внешний токен доступа при обмене токена обновления на новый локальный токен доступа. - person Kévin Chalet; 13.12.2018
comment
@Pinpoint я получаю эту ошибку { ошибка: invalid_client, error_description: указанный параметр «client_id» недействителен. } - person Khurram Ali; 12.03.2019
comment
client_id не является обязательным, поэтому я удаляю его, и теперь он работает нормально. - person Khurram Ali; 14.03.2019