如何在移动应用中无需交互式登录完成Azure身份验证
如何在移动应用中无需依赖交互式登录完成Azure身份验证?
预期
调用Azure资源前进行身份验证需以下参数:
- TenantId
- ClientId
- Secret
- Scope
问题
现有文档显示移动应用用户需手动完成Azure身份验证才能使用应用,但我的场景中,移动应用本身是Azure资源的用户/客户端,不希望通过登录窗口困扰终端用户。我原本以为仅需TenantId、ClientId、Secret和Scope即可让移动应用完成身份验证(无需终端用户交互式登录)。
总结
综上,如何在移动应用中无需依赖交互式登录完成Azure身份验证?
客户端代码
var tenantId = <some value>; var clientId = <some value>; var secret = <some value>; var scope = "https://management.azure.com/.default"; WebGateway.authToken = await BearerToken.Create(tenantId, clientId, secret, scope); var serviceKeysResponse = await WebGateway.postToAsync(someBaseUrl, someResource, somePayload); ...
Bearer令牌生成代码
public static class BearerToken { public async static Task<string> Create(string tenantId, string clientId, string clientSecret, string scope) { var tokenRequestBody = new Dictionary<string, string> { { "grant_type" , "client_credentials" }, { "client_id" , clientId }, { "client_secret", clientSecret }, { "scope" , scope } }; var url = $"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token"; var client = new HttpClient() { BaseAddress = new Uri(url) }; var content = new FormUrlEncodedContent(tokenRequestBody); var response = await client.PostAsync("", content); if (response.IsSuccessStatusCode) { var tokenResponse = await response.Content.ReadAsStringAsync(); var valueFor = JsonConvert.DeserializeObject<Root>(tokenResponse); return valueFor.access_token; } throw new Exception(response.ReasonPhrase); } public class Root { public string token_type { get; set; } public int expires_in { get; set; } public int ext_expires_in { get; set; } public string access_token { get; set; } } }
HTTP请求代码
let postToAsync (baseAddress:string) (resource:string) (payload:Object) = task { let tokenSource = new CancellationTokenSource(TimeSpan(0,3,0)); let token = tokenSource.Token; try Debug.WriteLine $"\n\nAttempting HTTP Post: {baseAddress}{resource}" use client = httpClient baseAddress client.DefaultRequestHeaders.Authorization <- AuthenticationHeaderValue("Bearer", authToken) client.DefaultRequestHeaders.Accept.Add(MediaTypeWithQualityHeaderValue("application/json")) let json = JsonConvert.SerializeObject(payload) let content = new StringContent(json, Encoding.UTF8, "application/json") let! response = client.PostAsync(resource, content, token) |> Async.AwaitTask Debug.WriteLine $"\n\n{response.StatusCode}:\n{baseAddress}{resource}\n\n" return response with ex -> Debug.WriteLine($"\n\nError: {baseAddress}{resource}\n{ex.GetBaseException().Message}") if ex.GetBaseException().Message = "timeout" || ex.GetBaseException().Message = "A task was canceled" then return new HttpResponseMessage(HttpStatusCode.RequestTimeout) else return new HttpResponseMessage(HttpStatusCode.BadRequest) }
内容的提问来源于stack exchange,提问作者Scott Nimrod
相关产品推荐
相关产品推荐

