【问题标题】:Migrating from Google OpenID to new OAuth 2从 Google OpenID 迁移到新的 OAuth 2
【发布时间】:2014-03-18 14:09:59
【问题描述】:

我看到已经有一些关于此的问题,但我发现没有一个涉及任何细节。

我之前使用过我自己的 DotNetOpenAuth 代码,但现在我决定切换到 Microsoft Wrapper 进行身份验证。无论如何,我发现这个非常好的 OAuth 客户端:

https://github.com/mj1856/DotNetOpenAuth.GoogleOAuth2

它似乎工作正常,但现在它涉及迁移部分。在我当前的登录系统中,我保存了 Google 返回的完整 OpenID URL,格式为:

https://www.google.com/accounts/o8/id?id=????????????????????????????????????

根据https://developers.google.com/accounts/docs/OpenID 此处的文档,我应该能够通过新的 OAuth 系统以某种方式获得该值。

我在 Auth 请求中包含了“openid.realm”参数。

    return BuildUri(AuthorizationEndpoint, new NameValueCollection
        {
            { "response_type", "code" },
            { "client_id", _clientId },
            { "scope", string.Join(" ", scopes) },
            { "redirect_uri", returnUrl.GetLeftPart(UriPartial.Path) },
            { "state", state },
            { "openid.realm", "http://myoldopenidrealm" }
        });

据我了解,文档应该是我需要做的所有事情。我已确保用于我的 OpenID 2 身份验证的 Realm 与我的返回 URL 相同。

完成后,我执行该令牌请求,据我了解,在这里我应该看到一个“open_id”字段,但我不明白如何获取它。

protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) {
    var postData = HttpUtility.ParseQueryString(string.Empty);
    postData.Add(new NameValueCollection
        {
            { "grant_type", "authorization_code" },
            { "code", authorizationCode },
            { "client_id", _clientId },
            { "client_secret", _clientSecret },
            { "redirect_uri", returnUrl.GetLeftPart(UriPartial.Path) },
        });

    var webRequest = (HttpWebRequest)WebRequest.Create(TokenEndpoint);

    webRequest.Method = "POST";
    webRequest.ContentType = "application/x-www-form-urlencoded";

    using (var s = webRequest.GetRequestStream())
    using (var sw = new StreamWriter(s))
        sw.Write(postData.ToString());

    using (var webResponse = webRequest.GetResponse()) {
        var responseStream = webResponse.GetResponseStream();
        if (responseStream == null)
            return null;

        using (var reader = new StreamReader(responseStream)) {
            var response = reader.ReadToEnd();
            var json = JObject.Parse(response);
            var accessToken = json.Value<string>("access_token");
            return accessToken;
        }
    }
}

这是文档所说的,我看不到“sub”或“openid_id”字段。

*该令牌请求的响应包括常用字段(access_token 等),加上一个 openid_id 字段和标准 OpenID Connect 子字段。在此上下文中您需要的字段是 openid_id 和 sub:*

【问题讨论】:

    标签: c# oauth openid dotnetopenauth google-oauth


    【解决方案1】:

    sub 和 openid_id 字段包含在 OpenID Connect ID token 中,而不是访问令牌中。

    您可以通过令牌端点(与您用于检索访问令牌的端点相同)获取 ID 令牌,或者您也可以直接从 OpenID Connect 身份验证请求中检索它(通过将 id_token 添加到 response_type 参数,可能会节省对令牌端点的后端调用)。

    希望有帮助!

    --

    如何获取 ID 令牌的示例

    (使用 oauthplayground 生成的流程——强烈推荐的工具来调试 OAuth2/OpenID Connect 流程)

    1. 转到https://developers.google.com/oauthplayground
    2. 选择(例如)Oauth2 API v2 userinfo.email 范围
    3. 点击授权 API
    4. 批准 OAuth2 请求
    5. 按“交换令牌授权码”按钮。

    您可以查看所有 http 请求/响应。有趣的是,对 Google 令牌 API 的调用的响应包含

    { “access_token”:“ya29.XYZ”, "token_type": "承载者", “expires_in”:3600, "refresh_token": "1/KgXYZ", “id_token”:“my.id.token” }

    您可以对获取的 ID 令牌(在本例中为“id”)的负载进行 base 64 解码,并获取所有相关的用户信息。要手动进行 base 64 解码,您可以使用任何在线工具(例如,参见 https://www.base64decode.org/)。

    【讨论】:

    • 能否请您详细说明如何执行此操作?
    • 不确定“这个”是什么意思。假设您正在询问如何获取 ID 令牌,这些是很好的起点:1)developers.google.com/accounts/docs/OAuth2Login 和 2)developers.google.com/accounts/cookbook/technologies/…
    • 抱歉,我花了好几天的时间苦读这份文档,需要一点生命线。您如何使用 OWIN 将 id_token 值添加到 response_type 参数?我尝试通过将它包含在 OApplyRedirect 方法中来添加它,我收到一个错误,即只允许参数的一个值。我可以对redirecturi 进行替换,但这似乎是一个黑客行为。任何建议将不胜感激。
    • 你能给一个代码示例吗?我假设您的意思是您将 response_type=code 替换为 `response_type=id_token' ?你是这个意思吗?您是否需要对身份验证和验证调用都执行此操作?
    • 抱歉,spanelives,不熟悉 OWIN。刚刚在我的回复中添加了一个示例(根据 Doug 的要求)。希望有帮助!
    猜你喜欢
    • 2014-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    相关资源
    最近更新 更多