无法对最新的GDrive代码使用ApplyAuthenticationToRequest调用

本文关键字:ApplyAuthenticationToRequest 调用 代码 GDrive 最新 | 更新日期: 2023-09-27 18:17:33

我正在做一个GDrive项目,这是10个多月前写的。前面获取Drive服务对象的代码是

private OAuth2Authenticator<AssertionFlowClient> authenticator;
private DriveService GetService(String userEmail)
    {
        X509Certificate2 certificate = new X509Certificate2(SERVICE_ACCOUNT_PKCS12_FILE_PATH, "notasecret", X509KeyStorageFlags.Exportable);
        var provider = new AssertionFlowClient(GoogleAuthenticationServer.Description, certificate)
        {
            ServiceAccountId = SERVICE_ACCOUNT_EMAIL,
            Scope = DriveService.Scopes.Drive.GetStringValue(),
            ServiceAccountUser = userEmail,
        };
        authenticator = new OAuth2Authenticator<AssertionFlowClient>(provider, AssertionFlowClient.GetState);
        return new DriveService(new BaseClientService.Initializer() { Authenticator = authenticator, ApplicationName = "Random" });
    }

随着最新的google drive api更改,我更改了代码以获取驱动器服务对象

private DriveService GetService(String userEmail)
    {
        X509Certificate2 certificate = new X509Certificate2(SERVICE_ACCOUNT_PKCS12_FILE_PATH, "notasecret", X509KeyStorageFlags.Exportable);
        ServiceAccountCredential credential = new ServiceAccountCredential(
       new ServiceAccountCredential.Initializer(SERVICE_ACCOUNT_EMAIL)
       {
           Scopes = new[] { DriveService.Scope.Drive },
           User = userEmail,
       }.FromCertificate(certificate));
        // Create the service.
        return new DriveService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = "Random",
        });
    }

我也有以下代码下载文件

 public void DownloadFile(string url, string fileName)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        //authenticator.ApplyAuthenticationToRequest(request);
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        System.IO.Stream received = response.GetResponseStream();
        using (System.IO.FileStream file = new System.IO.FileStream(fileName, System.IO.FileMode.Create, System.IO.FileAccess.Write))
        {
            Util.CopyStream(received, file);
        }
    }

这里的问题是,由于OAuth2Authenticator已弃用,因此随着获得驱动器服务对象的最新更改,我无法调用"ApplyAuthenticationToRequest"调用。没有调用该函数,我得到一个异常,"System.Net。web异常:远程服务器返回一个错误:(401)Unauthorized"。随着最新的变化,我如何才能调用"ApplyAuthenticationToRequest"函数,使调用能够成功。该函数还在项目中的其他2个地方使用。有人能帮帮我吗?

无法对最新的GDrive代码使用ApplyAuthenticationToRequest调用

显然对于service

来说也是可能的
        var file = service.Files.Get(fileID).Execute();
        var bytes = service.HttpClient.GetByteArrayAsync(file.DownloadUrl).Result;

你需要从google请求一个令牌。下面是从google

获取令牌的类
public class GoogleJsonWebToken
{
    public const string SCOPE_DRIVE_READONLY = "https://www.googleapis.com/auth/drive.readonly";
    public const string SCOPE_DRIVE = "https://www.googleapis.com/auth/drive";
    public static dynamic GetAccessToken(string clientIdEMail, string keyFilePath, string scope)
    {
        // certificate
        var certificate = new X509Certificate2(keyFilePath, "notasecret");
        // header
        var header = new { typ = "JWT", alg = "RS256" };
        // claimset
        var times = GetExpiryAndIssueDate();
        var claimset = new
        {
            iss = clientIdEMail,
            scope = scope,
            aud = "https://accounts.google.com/o/oauth2/token",
            iat = times[0],
            exp = times[1],
        };
        JavaScriptSerializer ser = new JavaScriptSerializer();
        // encoded header
        var headerSerialized = ser.Serialize(header);
        var headerBytes = Encoding.UTF8.GetBytes(headerSerialized);
        var headerEncoded = Convert.ToBase64String(headerBytes);
        // encoded claimset
        var claimsetSerialized = ser.Serialize(claimset);
        var claimsetBytes = Encoding.UTF8.GetBytes(claimsetSerialized);
        var claimsetEncoded = Convert.ToBase64String(claimsetBytes);
        // input
        var input = headerEncoded + "." + claimsetEncoded;
        var inputBytes = Encoding.UTF8.GetBytes(input);
        // signiture
        var rsa = certificate.PrivateKey as RSACryptoServiceProvider;
        var cspParam = new CspParameters
        {
            KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName,
            KeyNumber = rsa.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2
        };
        var aescsp = new RSACryptoServiceProvider(cspParam) { PersistKeyInCsp = false };
        var signatureBytes = aescsp.SignData(inputBytes, "SHA256");
        var signatureEncoded = Convert.ToBase64String(signatureBytes);
        // jwt
        var jwt = headerEncoded + "." + claimsetEncoded + "." + signatureEncoded;
        var client = new WebClient();
        client.Encoding = Encoding.UTF8;
        var uri = "https://accounts.google.com/o/oauth2/token";
        var content = new NameValueCollection();
        content["assertion"] = jwt;
        content["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";
        string response = Encoding.UTF8.GetString(client.UploadValues(uri, "POST", content));
        var result = ser.Deserialize<dynamic>(response);
        return result;
    }
    private static int[] GetExpiryAndIssueDate()
    {
        var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
        var issueTime = DateTime.UtcNow;
        var iat = (int)issueTime.Subtract(utc0).TotalSeconds;
        var exp = (int)issueTime.AddMinutes(55).Subtract(utc0).TotalSeconds;
        return new[] { iat, exp };
    }
}

对于下载本身,我使用这个

            public static byte[] GetFile(string fileID, out string contenttype, out string filename)
    {
        DALParameter dalp = new DALParameter();
        var gdEmail = dalp.GetParameter(INMDTO.Parameters.GoogleDriveLogin, INMDTO.ParametersLevel.General, 0);
        var credential = GetCertificate();
        var service = new DriveService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = "tttt",
        });
        string path = AppDomain.CurrentDomain.BaseDirectory + "App_Data''";
        string certFile = "gd.p12";
        string fullcertpath = Path.Combine(path, certFile);
        var email = gdEmail;
        var auth = GoogleJsonWebToken.GetAccessToken(email, fullcertpath, GoogleJsonWebToken.SCOPE_DRIVE_READONLY);
        var f = service.Files.Get(fileID).Execute();
        contenttype = f.MimeType;
        filename = f.OriginalFilename;
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(new Uri(f.DownloadUrl));
        req.Headers.Add("Authorization", auth["token_type"] + " " + auth["access_token"]);
        HttpWebResponse response = (HttpWebResponse)req.GetResponse();
        if (response.StatusCode == HttpStatusCode.OK)
        {
            Stream sourceStream = response.GetResponseStream(); // the ConnectStream
            byte[] array;
            using (var ms = new MemoryStream())
            {
                sourceStream.CopyTo(ms);
                array = ms.ToArray();
            }
            return array;
        }
        return null;
    }

这可能不是最好的解决方案,但它有效,我真的没有找到另一种方法来做它。希望这对你有所帮助。

相关文章:
  • 没有找到相关文章