web-dev-qa-db-ja.com

バックエンド検証フローを明確にしたGoogleログイン

さまざまなチュートリアルや記事を何時間も調査してきたので、ようやく質問に答えるようになりました。

Angular 7アプリケーションのすべてのユーザーにGoogleログイン認証の使用を強制したい。ただし、Google認証が完了したら、まずユーザーがバックエンドDB(PostgreSQL)に存在することを確認します。もしそうなら、私は2つの目的でJWTを発行したいと思います:

  1. Spring Boot RESTサービスへの今後の呼び出しが、承認されたユーザーに対してのみ実行されることを確認します。
  2. トークンを認識するAuthGuardを使用してAngularルートを保護します。

これまでのところ、gapi auth2 auth応答からid_tokenを取得して、Spring Boot POSTマッピングに転送することができましたが、どのOAuthを正確に特定するのに苦労しています。 2.0/OpenIdフロー/適切なSpring Bootのドキュメント/チュートリアルを入手するときに人生が難しくなることを目指しているグラント。

私が目指すべきフロー/グラント、および私の現在の方向性が有効であるかどうかを明確にすることができる人はいますか?

13
Rhys

私はGoogle Auth/OAuth 2.0/Credential Management APIにも取り組んでおり、ウェブ上の例やうさぎの穴からの失望に共感できます。

あなたの質問に次のように答えられるかわかりませんが、Credential Management APIとGoogleのフロントエンド審査を完了した後に私が行っていることです:-

public String ValidateToken(string idToken, string accessToken)
{
    bool isValid = false;
    string errorMessage = "Illegal Access Token: ";

    if (accessToken != null)
    {
        var tokeninfoRequest = new Oauth2Service().Tokeninfo();
        tokeninfoRequest.AccessToken = accessToken;
        Tokeninfo tokeninfo = null;
        try
        {
            tokeninfo = tokeninfoRequest.Execute();
            if (tokeninfo.IssuedTo != CLIENT_ID)
            {
                errorMessage += "Imposter";
            }
        }
        catch (Exception e)
        {
            errorMessage += e.Message;
        }
        isValid = true;
    }

    if (!isValid) abortRequest(401, errorMessage);

    errorMessage = "Invalid ID Token";
    string gplus_id = "";
    JwtSecurityToken JWToken = new JwtSecurityToken(idToken);

    Byte[][] certBytes = getCertBytes(GOOGLE_CERTS);
    Dictionary<String, X509Certificate2> certificates = new Dictionary<String, X509Certificate2>();
    for (int i = 0; i < certBytes.Length; i++)
    {
        X509Certificate2 certificate = new X509Certificate2(certBytes[i]);
        certificates.Add(certificate.Thumbprint, certificate);
    }

    TokenValidationParameters JWTparams = new TokenValidationParameters()
    {
        ValidateActor = false,
        ValidateAudience = true, 
        ValidAudience = CLIENT_ID,
        ValidateIssuer = true, 
        ValidIssuers = VALID_ISSUERS,
        ValidateIssuerSigningKey = true,
        RequireSignedTokens = true,
        IssuerSigningKeys = certificates.Values.Select(x => new X509SecurityKey(x)),
        IssuerSigningKeyResolver = (tokenString, securityToken, kid, parameters) =>
        {
            return certificates
           .Where(x => x.Key.ToUpper() == kid.ToUpper())
           .Select(x => new X509SecurityKey(x.Value));
        },
        ValidateLifetime = true,
        RequireExpirationTime = true,
        ClockSkew = TimeSpan.FromHours(13)
    };

    Claim[] claims = JWToken.Claims.ToArray<Claim>();
    for (int i = 0; i < claims.Length; i++)
    {
        if (claims[i].Type.Equals("sub"))
        {
            gplus_id = claims[i].Value;
            break;
        }
    }

    if (gplus_id == null) abortRequest(401, "Invalid Google id");

    SecurityToken validatedToken;
    ClaimsPrincipal cp;
    JwtSecurityTokenHandler JWThndlr = new JwtSecurityTokenHandler();
    try
    {
        cp = JWThndlr.ValidateToken(idToken, JWTparams, out validatedToken);
    }
    catch
    {
        cp = null;
    }

    if (cp == null) abortRequest(401, "Invalid ID Token");

    return "{\"success\": true}";
}
0
McMurphy