如何使用移动应用程序向 Azure 进行身份验证(不依赖交互式登录)?
期望:
据我了解,在调用 Azure 资源之前需要使用以下值进行身份验证:
• 租户 ID • 客户端ID • 秘密 • 范围
问题:
以下文档建议移动应用程序用户在使用移动应用程序之前需要手动向Azure进行身份验证。
就我而言,移动应用程序本身旨在成为 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);
...
不记名代币:
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)
}
您正在幕后使用 OAuth2。
应用程序必须实现一个工作流程来检索“授权”令牌,这不是对用户进行身份验证的工作流程。这由授权服务器负责,未指定,大多数提供商都实现 OpenID Connect,使您的应用程序重定向到身份提供商网站(Google、Amazon、Facebook、Apple、Microsoft、StackExchange...)。从代码示例的外观来看,我认为您的工具包正在为您实现所有复杂的东西。
我期望 TenantId、ClientId、Secret 和 Scope 是移动应用程序进行身份验证所需的全部内容(无需最终用户进行交互式登录)。public您正在验证 OAuth2 客户端:移动应用程序。我不知道你的确切用例,但在不受信任(消费者)系统上运行的客户端应该是不携带秘密的公共客户端。您应该评估在 OAuth2 定义中是否需要
或confidential客户端。
总之,如何使用移动应用程序在不依赖交互式登录的情况下通过 Azure 进行身份验证?有多种可能的方法,但肯定会大大降低身份验证强度和安全性。 我认为您遇到了 XY 问题,并且想解决这个问题。
因此,我不想让最终用户与使用 Azure 资源的登录窗口混淆。
我建议您告知用户他们将在 Azure 资源上进行身份验证。
这样他们就不会因进入第三方身份验证工作流程而感到困惑。身份验证很难正确进行,请专注于应用程序,然后让第三方为您处理。 这种方式比密码更安全、更灵活,当前的最佳实践是将这些与 OTP、安全密钥、生物识别或您必须实施的任何其他因素配对,因为安全提供商不会提供仅密码身份验证。