Google OpenID nach OpenID Connect migrieren: openid_id stimmt nicht überein

Ich habe mit der Migration von Google OpenID zu OpenID Connect mit OAuth 2.0 begonnenDokumentation. Ich kann den Workflow zum Abrufen von openid_id und sub im id_token vom Token-Endpunkt erfolgreich abschließen, aber wenn dies der Fall ist, stimmt openid_id nicht mit der in unserem System vorhandenen ID überein. Verhindern, dass ich den vorhandenen Benutzer der neuen ID zuordne und dass sich der Benutzer bei unserer Anwendung anmeldet (oder möglicherweise als eine andere Person anmelden darf). Die ID hat das richtige Format, stimmt aber nicht überein.

Ich habe den Parameter openid.realm auf unseren vorhandenen Parameter openid.realm gesetzt und die Weiterleitung wie in der Dokumentation angegeben festgelegt. Dies geschieht sowohl lokal als auch in unseren von Azure gehosteten Umgebungen. Ich verwende das JWT.JsonWebToken, um das id_token zu dekodieren, aber ich habe auch überprüft, dass es ordnungsgemäß dekodiert wurde, indem ich den im Web gehosteten Dekoder bei Google verwendet habe:JWT Decoder, und ich fand denselben OpenID-Bezeichner, der nicht mit dem übereinstimmt, den wir derzeit für diesen Benutzer haben. Ich sollte auch beachten, dass ich versucht habe, den Profilbereich hinzuzufügen, aber das machte keinen Unterschied.

Wir verwenden DotNetOpenAuth.OpenId für unser ursprüngliches System, daher glaube ich nicht, dass das Problem dort liegt. Ich habe den ClaimedIdentifier untersucht, der Teil der Antwort ist, und er stimmt mit dem überein, was wir in unserem System für openId gespeichert haben, damit wir ihn nicht falsch speichern.

Unten sehen Sie, was wir verwenden, um den Uri für die Authentifizierungsanforderung zu generieren. Es handelt sich hauptsächlich um eine modifizierte Version des DotNetOpenAuth.GoogleOAuth2-Clients.

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;
        }

Und hier ist, was wir verwenden, um die Anfrage an den Token-Endpunkt zu generieren.

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

Antworten auf die Frage(1)

Ihre Antwort auf die Frage