【问题标题】:Authenticating Web Api using Azure B2C and MSAL in Xamarin Mobile App在 Xamarin 移动应用程序中使用 Azure B2C 和 MSAL 对 Web Api 进行身份验证
【发布时间】:2019-01-30 14:13:19
【问题描述】:

当我尝试授权使用 MSAL 从移动应用程序使用我的 Web Api 时,我收到 401 Unauthorized 消息。

为了保护无辜者,部分名称和 App Id 已更改。 我知道这是一篇非常长的帖子,但我正在尝试提供尽可能多的信息以获得解决方案。

使用 Visual Studio 2017 在 ASP.NET 核心中开发的 Web 应用程序 使用 Xamarin Forms 和 MSAL 开发的移动应用

Web API 地址是: https://mywebapi.azurewebsites.net

我想打: https://mywebapi.azurewebsites.net/api/workdiary

我可以通过租户使用我的移动应用登录和注销:myTenant.onmicrosoft.com

但是,一旦登录,我就无法使用通过以下方式获得的缓存令牌 AcquireTokenSilentAsync 从我的 Web Api 授权 GET。


问题可能出在哪里的一些线索:

HTTP 请求中的参数不正确:

-当我尝试按如下方式访问我的 Web Api 时-:

AuthenticationResult ar = await PCA.AcquireTokenSilentAsync(Scopes, GetUserByPolicy(PCA.Users,PolicySignUpSignIn), Authority, false);
string token = ar.AccessToken;
var baseAddr = new Uri(ApiEndpoint);
var client = new HttpClient { BaseAddress = baseAddr };
var workDiaryUri = new Uri(baseAddr, "api/workdiary");
var request = new HttpRequestMessage(HttpMethod.Get, workDiaryUri);
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();

...响应显示状态为 401 Unauthorized。

-设置了以下静态变量-:

public static PublicClientApplication PCA = null;

// Azure AD B2C Coordinates
public static string Tenant = "myTenant.onmicrosoft.com";
public static string ClientID = "xyz456";
public static string PolicySignUpSignIn = "B2C_1_GeneralSignUpSignIn";
public static string[] Scopes = { "https://myTenant.onmicrosoft.com/api/mymobile.read.only" };
public static string ApiEndpoint = "https://mywebapi.azurewebsites.net";
public static string AuthorityBase = $"https://login.microsoftonline.com/tfp/{Tenant}/";
public static string Authority = $"{AuthorityBase}{PolicySignUpSignIn}";
public static UIParent UiParent = null;

-PublicClientApplication 设置如下-:

PCA = new PublicClientApplication(ClientID, Authority);
PCA.RedirectUri = $"msal{ClientID}://auth";

什么有效:

移动应用使用 AcquireTokenAsync 命令注册和登录没有问题。 但是,当尝试访问 Web Api 时,从 AcquireTokenSilentAsync 获取的令牌似乎未授权用户。

-App 尝试通过在 try catch 中使用 AcquireTokenSilentAsync 来使用缓存的 Token(这会成功执行)-:

AuthenticationResult ar = await PCA.AcquireTokenSilentAsync(Scopes, GetUserByPolicy(PCA.Users, PolicySignUpSignIn), Authority, false);

-如果没有可用的缓存令牌,则用户通过单击按钮执行注册登录过程(这也成功执行)-:

AuthenticationResult ar = await PCA.AcquireTokenAsync(Scopes, GetUserByPolicy(PCA.Users, PolicySignUpSignIn), UiParent);

“注册或登录”策略的 Azure B2C 租户设置不正确:

-在帐篷中我设置了 2 个应用程序-:

我的移动前端

  • Web App/Web Api 设置为 NO
  • Native Client 设置为 YES
  • 未添加任何键
  • 授予 My Mobile API 的 API 访问权限,具有基本的只读权限 scope *不知道我是否需要这个(请告知)
  • 没有发布的范围

(见图NativeAppProperties1 & NativeAppProperties2)

NativeAppProperties1

NativeAppProperties2

与

我的移动 API

  • 已将 Web App/Web Api 设置为 YES
  • Native Client 设置为 NO
  • 添加了 1 个 App Key *不知道我是否需要这个(请告知)
  • 授予 My Mobile API 的 API 访问权限,具有基本的只读权限 scope *不知道我是否需要这个(请告知)
  • 1 Scope Published (mymobile.read.only) 仅限基本权限
    *不知道我是否需要这个(请告知)

    (见附件中的图WebApiProperties1 & WebApiProperties2)

WebApiProperties1

WebApiProperties2

-我还设置了注册或登录策略-:

B2C_1_GeneralSignUpSignIn

- 不确定我是否需要将我的移动 API 添加到访问令牌(请 建议)

(见附件中的SignUpSignInProperties图)

SignUpSignInProperties

-对于身份提供者,我只有本地帐户-“电子邮件”设置-。


Web Api 中的服务设置不正确:

在我的 WebApi 中注释掉 [Authorize] 时,我可以在本地 IIS 测试和发布到 Azure 时成功运行 GET 和 POST 请求。 添加 [Authorize] 命令会按预期给出 401 错误。

-appsettings.json 文件包含以下内容-:

"Authentication": {
    "AzureAd": {
      "Tenant": "myTenant.onmicrosoft.com",
      "ClientId": "abc123",
      "Policy": "B2C_1_GeneralSignUpSignIn"
    }
}

-Startup.Configure 包含以下内容-:

app.UseAuthentication();
app.UseMvc();

-Startup.ConfigureServices 是一个如下-:

services.AddAuthentication(options =>
{
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
 })
.AddJwtBearer(options => {
    options.RequireHttpsMetadata = false;
    options.Audience = "abc123";
    options.Events = new JwtBearerEvents
    {
        OnAuthenticationFailed = AuthenticationFailed
     };

     options.Authority = string.Format("myTenant.onmicrosoft.com/api", "B2C_1_GeneralSignUpSignIn");                      
     });


services.AddDbContext<WorkDiaryContext>(options =>
      options.UseInMemoryDatabase("WorkDiaryDB"));

services.AddMvc()
       .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

【问题讨论】:

  • 您使用的是哪个 ADAL 版本?

标签: xamarin xamarin.forms visual-studio-2017 asp.net-core-webapi azure-ad-b2c


【解决方案1】:

历经千辛万苦,答案终于揭晓了。

2 个非常小的变化:

第一个只是可怕的斜线。 移动应用中 ApiEndpoint 的静态变量末尾需要一个斜线:

public static string ApiEndpoint = "https://mywebapi.azurewebsites.net/";

第二个是在我和 Microsoft 支持之间,我们无法找到任何明确的文档来概述这种所需的格式,但它非常具体。 Web Api 的 Startup.ConfigureServices 中的 Authority 选项应具有以下格式:

options.Authority = "https://login.microsoftonline.com/tfp/myTenant.onmicrosoft.com/B2C_1_GeneralSignUpSignIn/v2.0/";

我希望这对可能遇到相同问题的人有所帮助。

【讨论】:

    猜你喜欢
    • 2017-12-11
    • 2017-08-07
    • 2021-12-26
    • 2021-03-14
    • 2016-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多