通过App Engine连接GCP Cloud SQL SQL Server时遇权限及连接错误
看起来你碰到了两个关联的问题:部署到App Engine后登录SQL Server失败,本地用Cloud Proxy能连但Dotnet抛错。我来帮你一步步排查解决:
一、搞定App Engine上的登录失败错误(令牌验证/缺少端点权限)
先看第一个错误:用户'\9b73cfe90ee8d1d$'登录失败。原因:基于令牌的服务器访问验证因基础架构错误失败,登录缺少连接端点权限。这个奇怪的用户ID其实是App Engine默认服务账号的SID,说明你的应用要么在尝试用Cloud IAM身份验证但权限没配对,要么是SQL身份验证的配置有冲突。
1. 先确认SQL Server的身份验证模式
登录Cloud Console进你的SQL Server实例,看「身份验证」标签:
- 如果你想用连接字符串里的
sqlserver账号(SQL身份验证):确保「SQL Server身份验证」是开启的,而且这个账号有cliche数据库的访问权限(比如给它加个db_owner或者读写角色)。 - 如果你想用Cloud IAM身份验证(靠App Engine服务账号登录):得给App Engine的默认服务账号(格式是
[你的项目ID]@appspot.gserviceaccount.com)两个权限:项目级的「Cloud SQL Client」角色,以及SQL实例级的「Cloud SQL Instance User」权限(在实例的「权限」标签页添加)。
2. 修正连接字符串(关键中的关键)
如果用SQL身份验证,你的连接字符串必须补两个参数,还要明确端口:
"ConnectionStrings": { "default": "Server=127.0.0.1,1433;Database=cliche;User Id=sqlserver;Password=password;Encrypt=True;TrustServerCertificate=True;" }
为啥要加这些?Cloud SQL强制要求加密连接,TrustServerCertificate=True是跳过本地证书验证(因为Proxy转发的连接用的是自签证书);端口,1433不能丢,SQL Server默认监听这个端口,Cloud Proxy会把它映射到本地127.0.0.1。
如果用Cloud IAM身份验证,连接字符串不用密码,改成这样(适用于.NET 6+):
"ConnectionStrings": { "default": "Server=127.0.0.1,1433;Database=cliche;User Id=[你的服务账号邮箱];Encrypt=True;TrustServerCertificate=True;Authentication=Active Directory Default;" }
3. 权限配置后记得重启App Engine实例
有时候IAM权限不会立刻生效,重启一下你的App Engine服务,让新权限加载进去。
二、解决本地Dotnet连接Cloud Proxy的网络错误
你说本地用Proxy能连,但Dotnet抛TCP Provider,错误:40,这基本是连接字符串或者Proxy配置的问题:
1. 检查Cloud Proxy的启动命令
启动Proxy的时候要指定SQL Server的端口,命令应该是这样的:
./cloud-sql-proxy shared-resources-291914:europe-west2:sqlserver-edutec --port 1433
别改端口,除非你本地的SQL Server已经占了1433(那可以改成1434之类的,后面连接字符串也要对应改)。
2. 本地连接字符串和App Engine的要一致
同样要加Encrypt=True和TrustServerCertificate=True,并且明确端口:
"ConnectionStrings": { "default": "Server=127.0.0.1,1433;Database=cliche;User Id=sqlserver;Password=password;Encrypt=True;TrustServerCertificate=True;" }
3. 排查本地环境问题
- 先用SSMS连
127.0.0.1,1433,用相同的账号密码,如果SSMS能连但Dotnet不能,那肯定是Dotnet项目的配置问题——比如appsettings.json没被正确读取,或者环境变量覆盖了连接字符串。可以在启动时加一行代码输出连接字符串,确认是不是你配置的那个。 - 如果本地装了SQL Server,默认会占1433端口,这时候给Proxy换个端口(比如
--port 1434),然后连接字符串改成127.0.0.1,1434就行。
最后再核对一下App Engine的yaml配置
你的app.yaml里的beta_settings是对的,不用改:
beta_settings: cloud_sql_instances: shared-resources-291914:europe-west2:sqlserver-edutec
按上面的步骤走,应该能解决这两个问题。如果还是不行,再检查一下SQL Server实例的防火墙规则(不过App Engine用Proxy连接不需要开公共IP防火墙),或者看看App Engine的日志有没有更详细的错误信息。
内容的提问来源于stack exchange,提问作者Louis Campbell

