Обмен гугле сведения об идентификаторе маркера для местных openId маркер с#


Я использую этот проект github https://github.com/openiddict/openiddict-core что замечательно. Но я застрял на том, какие процедуры должны быть, или как их реализовать, когда пользователь использует внешний поставщик удостоверений, например, я буду использовать google.

У меня работает приложение angular2 с ядром aspnet webAPI. Все мои локальные логины работают отлично, я вызываю connect/token с именем пользователя и паролем, и возвращается accessToken.

Теперь мне нужно реализовать google как внешний поставщик удостоверений личности. Я выполнил все шаги здесь , чтобы реализовать кнопку входа в google. Это открывает всплывающее окно, когда пользователь входит в систему. Это код, который я создал для своей кнопки google.

// Angular hook that allows for interaction with elements inserted by the
// rendering of a view.
ngAfterViewInit() {
    // check if the google client id is in the pages meta tags
    if (document.querySelector("meta[name='google-signin-client_id']")) {
        // Converts the Google login button stub to an actual button.
        gapi.signin2.render(
            'google-login-button',
            {
                "onSuccess": this.onGoogleLoginSuccess,
                "scope": "profile",
                "theme": "dark"
            });
    }
}

onGoogleLoginSuccess(loggedInUser) {
    let idToken = loggedInUser.getAuthResponse().id_token;

    // here i can pass the idToken up to my server and validate it
}

Теперь у меня есть idToken от google. Следующий шаг на страницах google, найденных здесь , говорит, что мне нужно проверить Google accessToken, что я могу сделать, но как я могу обменять accessToken, который у меня есть от google, и создать локальный accessToken, который может быть использован на моем приложении?

1 4

1 ответ:

Следующий шаг на страницах google, найденных здесь, говорит, что мне нужно проверить Google accessToken, что я могу сделать, но как я могу обменять accessToken, который у меня есть от google, и создать локальный accessToken, который можно использовать в моем приложении?
Поток, который вы пытаетесь реализовать, известен какassertion grant . Вы можете прочитать этот другой пост SO для получения дополнительной информации об этом.

OpenIddict полностью поддерживает пользовательские гранты, так что это что-то вы можете легко реализовать в своей конечной точке токена действие:

[HttpPost("~/connect/token")]
[Produces("application/json")]
public IActionResult Exchange(OpenIdConnectRequest request)
{
    if (request.IsPasswordGrantType())
    {
        // ...
    }

    else if (request.GrantType == "urn:ietf:params:oauth:grant-type:google_identity_token")
    {
        // Reject the request if the "assertion" parameter is missing.
        if (string.IsNullOrEmpty(request.Assertion))
        {
            return BadRequest(new OpenIdConnectResponse
            {
                Error = OpenIdConnectConstants.Errors.InvalidRequest,
                ErrorDescription = "The mandatory 'assertion' parameter was missing."
            });
        }

        // 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);

        // Manually validate the identity token issued by Google,
        // including the issuer, the signature and the audience.
        // Then, copy the claims you need to the "identity" instance.

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

        ticket.SetScopes(
            OpenIdConnectConstants.Scopes.OpenId,
            OpenIdConnectConstants.Scopes.OfflineAccess);

        return SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme);
    }

    return BadRequest(new OpenIdConnectResponse
    {
        Error = OpenIdConnectConstants.Errors.UnsupportedGrantType,
        ErrorDescription = "The specified grant type is not supported."
    });
}

Обратите внимание, что вы также должны включить его в openiddict options:

// Register the OpenIddict services, including the default Entity Framework stores.
services.AddOpenIddict()
    // Register the Entity Framework stores.
    .AddEntityFrameworkCoreStores<ApplicationDbContext>()

    // Register the ASP.NET Core MVC binder used by OpenIddict.
    // Note: if you don't call this method, you won't be able to
    // bind OpenIdConnectRequest or OpenIdConnectResponse parameters.
    .AddMvcBinders()

    // Enable the token endpoint.
    .EnableTokenEndpoint("/connect/token")

    // Enable the password flow, the refresh
    // token flow and a custom grant type.
    .AllowPasswordFlow()
    .AllowRefreshTokenFlow()
    .AllowCustomFlow("urn:ietf:params:oauth:grant-type:google_identity_token")

    // During development, you can disable the HTTPS requirement.
    .DisableHttpsRequirement();

При отправке запроса на маркер обязательно используйте правильный grant_type и отправьте свой id_token в качестве параметра assertion, и он должен работать. Вот пример с Postman (для токенов доступа Facebook, но он работает точно так же):

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

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