.NET Core 3.1项目调用Google Drive API时提示‘Cannot get credential when not authenticated’的原因排查
我来帮你梳理几个大概率导致这个认证问题的点,按优先级排序:
1. 初始认证未请求Drive API的必要作用域
这是最常见的问题!你在AddGoogleOpenIdConnect的配置里,没有显式添加Drive只读权限的作用域。虽然控制器方法加了[GoogleScopedAuthorize(DriveService.ScopeConstants.DriveReadonly)],但用户第一次登录时,你的应用没向Google请求这个权限,后续自然拿不到包含该作用域的凭证。
解决方法:在OpenID Connect配置中添加对应的scope:
.AddGoogleOpenIdConnect(options => { options.ClientId = "<client_id>"; options.ClientSecret = "<secret>"; // 新增这一行,请求Drive只读权限 options.Scope.Add(DriveService.Scope.DriveReadonly); });
2. 控制器方法缺少认证保护
[GoogleScopedAuthorize]主要负责检查作用域,但如果你的方法没有被[Authorize]标记(或者该属性没有隐含强制认证),用户可能在未登录的情况下直接调用接口,触发“未认证”错误。
建议给控制器或目标方法加上[Authorize]:
[Authorize] [GoogleScopedAuthorize(DriveService.ScopeConstants.DriveReadonly)] public async Task<List<GDFolder>> GetRoot([FromServices] IGoogleAuthProvider auth) { // ... 你的业务代码 }
3. 中间件顺序配置错误
ASP.NET Core的中间件顺序非常关键!UseAuthentication()和UseAuthorization()必须放在UseRouting()之后、UseEndpoints()之前。如果顺序颠倒,认证信息无法被正确传递到请求处理流程中。
正确的Startup配置顺序应该是:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // ... 其他中间件(如UseHttpsRedirection、UseStaticFiles) app.UseRouting(); // 认证和授权必须在路由之后、端点之前 app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
4. 未配置保存Token到Cookie
如果你的OpenID Connect配置没开启SaveTokens = true,Google返回的访问令牌不会被保存到Cookie中,IGoogleAuthProvider就无法从中获取凭证。
添加这个配置项:
.AddGoogleOpenIdConnect(options => { options.ClientId = "<client_id>"; options.ClientSecret = "<secret>"; options.Scope.Add(DriveService.Scope.DriveReadonly); // 必须开启这个,才能将Token持久化到Cookie options.SaveTokens = true; });
5. 测试时未完成登录流程
别忘了先完成Google OAuth登录流程!如果直接匿名调用这个接口,肯定会触发未认证错误。可以先访问一个需要登录的页面,完成登录后再调用Drive API接口。
内容的提问来源于stack exchange,提问作者ChrisP

