【问题标题】:Migrating Google OpenID to OpenID Connect: openid_id does not match将 Google OpenID 迁移到 OpenID Connect:openid_id 不匹配
【发布时间】:2014-04-03 15:37:05
【问题描述】:

按照Documentation 中介绍的内容,我已开始使用 OAuth 2.0 从 Google OpenID 迁移到 OpenID Connect。我能够成功完成从令牌端点检索 id_token 中的 openid_id 和 sub 的工作流程,但是当我这样做时,openid_id 与我们系统中的现有标识符不匹配。阻止我将现有用户映射到新 ID 并阻止用户登录我们的应用程序(或可能被允许以其他人身份登录)。 id 格式正确,但不匹配。

我已将 openid.realm 参数设置为我们现有的 openid.realm,并将重定向设置为与文档建议的相同。这发生在本地和我们的 Azure 托管环境中。我正在使用 JWT.JsonWebToken 对 id_token 进行解码,但我还通过使用 google 上的网络托管解码器验证了它是否被正确解码:JWT Decoder,并且我想出了与我们不匹配的相同 OpenID 标识符目前有该用户。我还应该注意,我也尝试过添加配置文件范围,但这没有任何区别。

我们将 DotNetOpenAuth.OpenId 用于我们的原始系统,所以我认为问题不在于那里。我检查了作为响应一部分的 ClaimedIdentifier,它确实与我们在系统中为 openId 保存的内容相匹配,因此我们没有错误地保存它。

以下是我们用来为身份验证请求生成 Uri 的内容。它主要是 DotNetOpenAuth.GoogleOAuth2 客户端的修改版本。

protected static Uri GetServiceLoginUrl(Uri returnUrl)
    {
        var state = string.IsNullOrEmpty(returnUrl.Query) ? string.Empty : returnUrl.Query.Substring(1);

        return BuildUri(AuthorizationEndpoint, new NameValueCollection
            {
                { "response_type", "code" },
                { "client_id", AppId },
                { "scope", "openid" },
                { "prompt", "select_account"},
                { "openid.realm", CloudServiceConfiguration.GetDNSName() },
                { "redirect_uri", returnUrl.GetLeftPart(UriPartial.Path) },
                { "state", state },
            });
    }

private static Uri BuildUri(string baseUri, NameValueCollection queryParameters)
        {
            var q = HttpUtility.ParseQueryString(string.Empty);
            q.Add(queryParameters);
            var builder = new UriBuilder(baseUri) { Query = q.ToString() };
            return builder.Uri;
        }

这是我们用来生成对令牌端点的请求的内容。

protected static Tuple<string, string> GetAuthTokens(Uri returnUrl, string authorizationCode)
    {
        var postData = HttpUtility.ParseQueryString(string.Empty);
        postData.Add(new NameValueCollection
            {
                { "grant_type", "authorization_code" },
                { "code", authorizationCode },
                { "client_id", AppId },
                { "client_secret", AppSecret },
                { "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");
                var idToken = json.Value<string>("id_token");
                return new Tuple<string,string>(accessToken,idToken);
            }
        }
    }

【问题讨论】:

  • 使用上面的方法我遇到了在额外数据中没有返回 openid 令牌的问题。你是怎么把它退回来的?

标签: c# openid dotnetopenauth google-oauth google-openid


【解决方案1】:

请确保您在迁移流程中使用的 openid.realm 值与在初始 OpenID2 流程中使用的相同:这些值中的任何不匹配(即使是缺少尾部斜杠字符)都会导致到完全不同的 openid 标识符值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-17
    • 2015-02-09
    • 1970-01-01
    相关资源
    最近更新 更多