Google MVC 身份验证问题:'AppFlowMetaData' 的类型初始值设定项抛出异常。但是代码在本地工作

Google MVC Auth Issue: The type initializer for 'AppFlowMetaData' threw an exception. But the code works locally

首先:我看到其他几个线程在谈论类似的问题,但是这些线程的答案只是指向我在代码中用作参考的页面,所以请不要杀死这只是因为它看起来很相似。

我只在生产 IIS 实例上收到错误 "The type initializer for 'Models.AppFlowMetaData' threw an exception." BUT。这在本地工作正常,我已经三次检查了 return url (无论如何这给出了不同的错误) 我唯一能想到的是 Auth 被某种方式阻止了. Google 开发控制台没有显示任何错误。

错误发生在以下代码中:

 private static          string[]                scopes  = { SheetsService.Scope.Spreadsheets, DriveService.Scope.Drive };

    private static readonly IAuthorizationCodeFlow  flow    = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer {
                ClientSecrets = new ClientSecrets {
                    ClientId        = "[App id].apps.googleusercontent.com",
                    ClientSecret    = "[secret]" },
                Scopes          = scopes,
                DataStore       = new FileDataStore("Drive.Api.Auth.Store") });

    public override IAuthorizationCodeFlow Flow { get { return flow; } }

以上代码基于 google 网站上给出的身份验证示例:Google API Auth for MVC

以上代码调用自:

 private async Task<UserCredential> GetGoogleCreds()
    {
        Google.Apis.Auth.OAuth2.Web.AuthorizationCodeWebApp.AuthResult result;

        try
        {
            var log = LogManager.GetCurrentClassLogger();
            log.Info("GetGoogleCreds: getting temp appflowmetadata");
            var temp = new Models.AppFlowMetaData();
            result = await new AuthorizationCodeMvcApp(this, new Models.AppFlowMetaData()).AuthorizeAsync(new CancellationTokenSource().Token);

            if (result.Credential == null)
            {
                LoggingIntoGoogle = null;
                throw new ApiException(500, result.RedirectUri);
            }

            return result.Credential;
        }
        catch(ApiException ex)
        {
            throw ex;
        }
        catch(Exception ex)
        {
            ERROR(ref ex);
            throw ex;
        }

        return null;
    }

上面抛出的 APIException 告诉调用进程 Google 还没有登录,所以它重定向到 Google OAuth 结果(当它可以到达那么远时)。

好的,这里的问题是 FileDataStore 和缺少 Google 实际记录的东西。

如果流中的文件数据存储保留为 Web 示例中的原样,它在适当的 IIS 服务器上失败。

它尝试在 windows 受限文件夹下创建文件夹 (该示例表明它使用 google 驱动器,但实际上没有)(程序数据等),这当然会在 low-security 服务器设置上导致各种错误。

您必须使用 Server.MapPath() 并映射到可以写入的本地网站文件夹,例如 app_data。

对于上面的示例,我通过使用额外的组合让 google 使用 App_Data 下的文件夹来使其工作:

private static readonly IAuthorizationCodeFlow  flow    = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer {
                ClientSecrets = new ClientSecrets {
                    ClientId        = "[client id].apps.googleusercontent.com",
                    ClientSecret    = "[secret]" },
                Scopes          = scopes,
                DataStore       = new FileDataStore(Path.Combine(HttpContext.Current.Server.MapPath("~/App_Data/"), "FileDataStore")) });