我正在尝试使用 Azure AD B2C 登录/注册流程来学习 ASP.Net。我在这里运行演示:
https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-web-api-dotnet?tabs=app-reg-ga
演示的 C# 代码可以从 https://github.com/Azure-Samples/active-directory-b2c-dotnet-webapp-and-webapi/archive/master.zip
下载我从一开始就完成了演示并完成了所有先决条件。
我现在已成功登录,当我在调试应用程序时单击待办事项列表链接时,出现用户未授权 (404) 错误。
如果我没有解释我认为我所看到的非常好,我提前道歉,因为我对 Azure 和网络编程非常陌生。我最熟悉与 SQL Server 交互的 Windows 桌面应用程序,但我正在努力扩展我的知识,所以请耐心等待。
正如我之前所说,我可以成功登录到应用程序,我相信这发生在 TaskWebApp 项目中。
这是发生错误的代码,在TaskWebApp项目的TasksController.cs中:
namespace TaskWebApp.Controllers
{
[Authorize]
public class TasksController : Controller
{
private readonly string apiEndpoint = Globals.ServiceUrl + "/api/tasks/";
// GET: Makes a call to the API and retrieves the list of tasks
public async Task<ActionResult> Index()
{
try
{
// Retrieve the token with the specified scopes
var scope = new string[] { Globals.ReadTasksScope };
IConfidentialClientApplication cca = MsalAppBuilder.BuildConfidentialClientApplication();
var accounts = await cca.GetAccountsAsync();
AuthenticationResult result = await cca.AcquireTokenSilent(scope, accounts.FirstOrDefault()).ExecuteAsync();
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, apiEndpoint);
// Add token to the Authorization header and make the request
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
HttpResponseMessage response = await client.SendAsync(request);
// Handle the response
switch (response.StatusCode)
{
case HttpStatusCode.OK:
string responseString = await response.Content.ReadAsStringAsync();
JArray tasks = JArray.Parse(responseString);
ViewBag.Tasks = tasks;
return View();
case HttpStatusCode.Unauthorized:
return ErrorAction("Please sign in again. " + response.ReasonPhrase);
default:
return ErrorAction("Error. Status code = " + response.StatusCode + ": " + response.ReasonPhrase);
}
}
catch (MsalUiRequiredException ex)
{
/*
If the tokens have expired or become invalid for any reason, ask the user to sign in again.
Another cause of this exception is when you restart the app using InMemory cache.
It will get wiped out while the user will be authenticated still because of their cookies, requiring the TokenCache to be initialized again
through the sign in flow.
*/
return new RedirectResult("/Account/SignUpSignIn?redirectUrl=/Tasks");
}
catch (Exception ex)
{
return ErrorAction("Error reading to do list: " + ex.Message);
}
}
Switch 语句中的响应状态码为 404。
当我调试时,这是我看到的:
var 作用域返回 https://ShoppingCartB2C.onmicrosoft.com/tasks/demo.read
cca 返回(我在质疑 Authority 属性的格式):
accounts 什么都不返回。计数为 0。
我认为 0 个帐户是问题所在。
当我尝试获取结果时,它会转到 catch 块。
这是 TaskWebApp 项目的 Web.config:
<configuration>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="ida:Tenant" value="ShoppingCartB2C.onmicrosoft.com" />
<!--MSAL cache needs a tenantId along with the user's objectId to function. It retrieves these two from the claims returned in the id_token.
As tenantId is not guaranteed to be present in id_tokens issued by B2C unless the steps listed in this
document (https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/AAD-B2C-specifics#caching-with-b2c-in-msalnet).
If you are following the workarounds listed in the doc and tenantId claim (tid) is available in the user's token, then please change the
code in <ClaimsPrincipalsExtension.cs GetB2CMsalAccountId()> to let MSAL pick this from the claims instead -->
<add key="ida:TenantId" value="db1b052a-415c-4604-887c-e27b59860001" />
<add key="ida:ClientId" value="975f1457-e3e2-4cb8-b069-6b0b6b46611d" />
<add key="ida:ClientSecret" value="Gw4.3o-DRDr.j_828H-JMfsk_Jd1d-jQ5p" />
<add key="ida:AadInstance" value="https://ShoppingCartB2C.b2clogin.com/tfp/{0}/{1}" />
<add key="ida:RedirectUri" value="https://localhost:44316/" />
<add key="ida:SignUpSignInPolicyId" value="B2C_1_signupsignin1" />
<add key="ida:EditProfilePolicyId" value="b2c_1_profileediting1" />
<add key="ida:ResetPasswordPolicyId" value="b2c_1_passwordreset1" />
<add key="api:TaskServiceUrl" value="https://localhost:44332/" />
<!-- The following settings is used for requesting access tokens -->
<add key="api:ApiIdentifier" value="https://ShoppingCartB2C.onmicrosoft.com/tasks/" />
<add key="api:ReadScope" value="demo.read" />
<add key="api:WriteScope" value="demo.write" />
</appSettings>
对于 TaskService 项目:
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="ida:AadInstance" value="https://ShoppingCartB2C.b2clogin.com/{0}/{1}/v2.0/.well-known/openid-configuration" />
<add key="ida:Tenant" value="ShoppingCartB2C.onmicrosoft.com" />
<add key="ida:ClientId" value="975f1457-e3e2-4cb8-b069-6b0b6b46611d" />
<add key="ida:SignUpSignInPolicyId" value="B2C_1_signupsignin1" />
<!-- The following settings is used for requesting access tokens -->
<add key="api:ReadScope" value="demo.read" />
<add key="api:WriteScope" value="demo.write" />
</appSettings>
如果您想从 Azure 获取屏幕截图,或者对其配置有任何疑问,请随时提问。
我不担心暴露客户端机密或 AppId,因为我只是在观看演示。这永远不会成为生产应用。
我没有对演示进行任何代码修改。感谢您的帮助。