GoogleSmarthome JWT Creation

那年仲夏 提交于 2020-06-01 05:29:27

问题


The documentation is at Using OAuth 2.0 for Server to Server Applications You will notice in the documentation the disclaimer "don't do this but use the libraries". Unfortunately, there does NOT appear to be .Net Core libraries and I have suggested to the Smarthome program managers that support for .Net Core should be the same as provided for Java, node.js and Python.

However, I'm hunkered down, socially distanced and have some time available so I gave it a shot. There are a lot of moving parts here but to start I downloaded a p12 file instead of a JSON file (as indicated in the documentation) from the Google Console for the account.

The code:

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace MakeJWTTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string token = MakeJwt();
            Console.WriteLine();
            Console.WriteLine("The Final JWT: " + token );

        }

        public static string MakeJwt()
        {
            string jwt = string.Empty;
            string iss = "XXXXXXXXXXXXXXX-v2.iam.gserviceaccount.com";
            string scope = "https://www.googleapis.com/auth/homegraph";
            string aud = "https://oauth2.googleapis.com/token";
            string exp = EpochExpiration();
            string iat = EpochCurrentTime();
            string jwtHeader = "{\"alg\":\"RS256\",\"typ\":\"JWT\"}";

            Console.WriteLine("iss: " + iss);
            Console.WriteLine("scope: " + scope);
            Console.WriteLine("aud: " + aud);
            Console.WriteLine("exp: " + exp);
            Console.WriteLine("iat: " + iat);
            Console.WriteLine("JWT Header: " + jwtHeader);


            string claim = "{\"iss\": \"" + iss + "\",\"scope\": \"" + scope + "\",\"aud\": \"" + aud + "\",\"exp\": " +
                exp + ",\"iat\": " + iat + "}";



            var encodedHeader = Base64UrlEncoder.Encode(jwtHeader);
            Console.WriteLine("Encoded JWT Header: " + encodedHeader);
            var encodedClaim = Base64UrlEncoder.Encode(claim);

            string claimSet = encodedHeader + "." + encodedClaim;
            string sig = Sign(claimSet);
            jwt = claimSet + '.' + sig;
            return jwt;
        }

        public static string EpochExpiration()
        {
            DateTime epoch = DateTime.UnixEpoch;
            DateTime now = DateTime.UtcNow;
            DateTime expiration = now.AddMinutes(60);
            TimeSpan secondsSinceEpoch = expiration.Subtract(epoch);
            return secondsSinceEpoch.TotalSeconds.ToString().Substring(0, 10);
        }

        public static string EpochCurrentTime()
        {
            DateTime epoch = DateTime.UnixEpoch;
            DateTime now = DateTime.UtcNow;          
            TimeSpan secondsSinceEpoch = now.Subtract(epoch);
            return secondsSinceEpoch.TotalSeconds.ToString().Substring(0, 10);
        }

        public static string Sign( string toSHA256)
        {
            try
            {

                byte[] data = Encoding.ASCII.GetBytes(toSHA256);

               var certificate = new X509Certificate2(@"XXXXXXXXXXXXXXX-v2-6790af22aa27.p12", "notasecret", X509KeyStorageFlags.Exportable);


                RSACryptoServiceProvider key = new RSACryptoServiceProvider();
                //  byte[] key = certificate.PrivateKey.ExportPkcs8PrivateKey();
                key.FromXmlString(certificate.PrivateKey.ToXmlString(true));



                //Sign the data
                byte[] sig = key.SignData(data, CryptoConfig.MapNameToOID("SHA256"));

                return Base64UrlEncoder.Encode(sig);

            }
            catch { Exception e;  return null; }
        }

    }  
}

Run this program and I get:

scope: https://www.googleapis.com/auth/homegraph
aud: https://oauth2.googleapis.com/token
exp: 1586193162
iat: 1586189562
JWT Header: {"alg":"RS256","typ":"JWT"}
Encoded JWT Header: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9

The Final JWT: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiAibGltaXRlZG1vYmlsaXR5djJAbGltaXRlZC1tb2JpbGl0eS1zb2x1dGlvbnMtdjIuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iICJzY29wZSI6ICJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9hdXRoL2hvbWVncmFwaCJhdWQiOiAiaHR0cHM6Ly9vYXV0aDIuZ29vZ2xlYXBpcy5jb20vdG9rZW4iZXhwIjogIjE1ODYxOTMxNjIiaWF0IjogMTU4NjE4OTU2Mg.ZOX93iUhirtH2tf95XzLYrGIbTK8kABipfVa6DnD-sAe3WcRfLmLVIAybtHTHxC8frCuZtCeS4XMT-EC69kLy-ks5BWFTnaRwm0TfIeNzIVrGfJUVRchvaJLFM9-wX6svVa4fGHMp8pKttO22BI3sIEisxXx2tw6Ge_8QRZXjSCXD0rg5P-0S-pnd8omkgPv_PhhALqcwd9RTUpcAqcMDoyP7ZxpBSMt1EwySixctKz2y4sRCGC8xaxp5E5VnH3liz3xTNMY5QRNX-tMxVIunh0Qp9v7bkuuvnhrwbcjRPq9qTKlhfIQBmZvaA5-9hzJZOiWWHmCunMec1pZp0bAgQ

Press any key to close this window . . . 

I then run this from Powershell using curl:

.\curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.RZVpzWygMLuL-n3GwjW1_yhQhrqDacyvaXkuf8HcJl8EtXYjGjMaW5oiM5cgAaIorrqgYlp4DPF_GuncFqg9uDZrx7pMmCZ_yHfxhSCXru3gbXrZvAIicNQZMFxrEEn4REVuq7DjkTMyCMGCY1dpMa8aWfTQFt3Eh7smLchaZsU' https://oauth2.googleapis.com/token

Which returns:

{"error":"invalid_grant","error_description":"Invalid grant: account not found"}

Could be a bunch of things wrong here. Any thoughts welcomed.


回答1:


There were two errors in the code:

  1. The JSON string
                       claim = "{\"iss\": \"" + iss + "\",\"scope\": \"" + scope + 
                               "\",\"aud\": \"" + aud + "\",\"exp\": " +
                               exp + ",\"iat\": " + iat + "}";
  1. The DateTime needs to be UTC

And now it works.



来源:https://stackoverflow.com/questions/61068471/googlesmarthome-jwt-creation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!