如何将.NET MAUI Web Authenticator与Azure Functions后端集成实现谷歌认证
使用.NET MAUI Web Authenticator结合Azure Functions实现谷歌认证
1. 配置Azure Functions身份验证(启用谷歌提供商)
- 登录Azure门户,找到目标Function App,进入身份验证选项卡
- 点击添加身份提供者,选择谷歌
- 填入从Google Cloud平台获取的客户端ID和客户端密钥
- 在重定向URI区域,确保Azure自动生成的回调URL(格式:
https://<你的FunctionApp名称>.azurewebsites.net/.auth/login/google/callback)已被包含 - 展开高级设置,将MAUI应用的自定义回调URI(例如
myapp://callback)添加到允许的外部重定向URI列表 - 设置未认证请求的操作为「允许匿名请求(无动作)」,因为我们将通过Web Authenticator主动触发认证流程
- 保存配置
2. 配置Google Cloud平台OAuth凭据
- 登录Google Cloud Console,进入目标项目,打开API和服务 > 凭据
- 点击创建凭据 > OAuth客户端ID,应用类型选择Web应用
- 在已授权的重定向URI中添加两个地址:
- Azure Functions的谷歌登录回调URL(同步骤1中Azure自动生成的地址)
- MAUI应用的自定义回调URI(例如
myapp://callback)
- 保存后,记录生成的客户端ID和密钥,用于步骤1的Azure配置
3. 配置MAUI应用的自定义URI Scheme
Android(AndroidManifest.xml)
在<application>节点内添加intent-filter:
<activity android:name="microsoft.maui.authentication.WebAuthenticatorCallbackActivity"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="myapp" /> </intent-filter> </activity>
iOS(Info.plist)
添加CFBundleURLTypes配置:
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>myapp</string> </array> </dict> </array>
Windows(Package.appxmanifest)
在<Applications>节点内添加扩展:
<Extensions> <uap:Extension Category="windows.protocol"> <uap:Protocol Name="myapp"> <uap:DisplayName>My App Auth Callback</uap:DisplayName> </uap:Protocol> </uap:Extension> </Extensions>
4. MAUI端实现Web Authenticator认证流程
在MAUI项目的页面或ViewModel中添加认证逻辑:
using Microsoft.Maui.Authentication; public async Task<bool> AuthenticateWithGoogleAsync() { var authUrl = new Uri("https://<你的FunctionApp名称>.azurewebsites.net/.auth/login/google"); var callbackUrl = new Uri("myapp://callback"); try { var authResult = await WebAuthenticator.Default.AuthenticateAsync(authUrl, callbackUrl); // 提取Azure返回的身份令牌 var idToken = authResult.Properties["id_token"]; var accessToken = authResult.Properties["access_token"]; // 将令牌存入安全存储 await SecureStorage.Default.SetAsync("id_token", idToken); await SecureStorage.Default.SetAsync("access_token", accessToken); return true; } catch (Exception ex) { Console.WriteLine($"认证失败: {ex.Message}"); return false; } }
5. 调用Azure Functions时携带令牌
调用受保护的Function接口时,从安全存储取出令牌添加到请求头:
using System.Net.Http.Headers; public async Task CallProtectedFunctionAsync() { var accessToken = await SecureStorage.Default.GetAsync("access_token"); if (string.IsNullOrEmpty(accessToken)) { await AuthenticateWithGoogleAsync(); accessToken = await SecureStorage.Default.GetAsync("access_token"); } using var client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); var response = await client.GetAsync("https://<你的FunctionApp名称>.azurewebsites.net/api/MyProtectedFunction"); if (response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); // 处理返回内容 } }
6. Azure Functions端验证身份(可选)
Azure会自动将用户身份数据注入请求头,可在Function中直接读取:
[FunctionName("MyProtectedFunction")] public static async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log) { var userId = req.Headers["x-ms-client-principal-id"].FirstOrDefault(); var userName = req.Headers["x-ms-client-principal-name"].FirstOrDefault(); if (string.IsNullOrEmpty(userId)) { return new UnauthorizedResult(); } return new OkObjectResult($"Hello, {userName}! Your ID is {userId}"); }
注意:需将Function的
AuthorizationLevel设置为Anonymous,让Azure身份验证层先处理身份校验,再进入Function逻辑。
内容的提问来源于stack exchange,提问作者javrro
相关产品推荐
相关产品推荐

