从AddAzureADB2C切换到Microsoft.Identity.Web时,验证链接是什么?

6jjcrrmo  于 2023-05-29  发布在  DB2
关注(0)|答案(2)|浏览(229)

我有一个API,它在一个普通的、手写的HTML页面上有一个简单的“登录”链接(没有剃刀页面,没有asp页面,什么都没有)。在我登录后,cookie被存储,因此我可以使用swagger UI直接进行简单的API调用。这对测试和开发非常有用。
它使用Azure AD-B2C进行身份验证。
我遵循了MS文档here中的说明,以及像AzureADB2CDefaults obsolete, how do I replace it?这样的问题。简单地说,我替换了这个代码:

.AddAzureADB2C(AzureADB2CDefaults.AuthenticationScheme, "AzureADB2COpenID", "AzureADB2CCookie", AzureADB2CDefaults.AuthenticationScheme, options =>
{
     StartupValidator.B2cConfiguration.Bind(options);
});

这个新代码:

services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
       .AddMicrosoftIdentityWebApp(options => {
           StartupValidator.B2cConfiguration.Bind(options);
});

它编译和运行良好,但我的登录链接(同样,这只是一个简单的硬编码HTML页面)指向:

<a href='/AzureADB2C/Account/SignIn/AzureADB2C'>Sign-in</a> |

导航到该链接将访问本地服务器(当您进行开发时为localhost),然后middlewhere会神奇地将302重定向到一个URL,其中包含所有nonce值和所有其他填充的bits和bobs。
所以我的问题是使用新设置的新登录URL是什么?这只是一个仅用于开发和调试的普通HTML页面,所以我不想引入所有的Razor页面或任何类似的页面。这能实现吗?
更新时间2023年5月24日星期三10:39:14 AM EDT:
在建议从默认的asp.net核心webapp模板开始之后,我已经能够通过1)拉入Microsoft.Identity.Web.UI和2)在安装过程中调用services.AddRazorPages().AddMicrosoftIdentityUI();来取得进展。然后我可以点击/MicrosoftIdentity/Account/SignIn登录(不记名令牌也不可用)。
这不是一个真正的解决方案,因为它增加了所有的剃刀和UI依赖项,并显着增加了容器的大小。有没有 * 任何 * 方法可以做到这一点,而不添加所有的UI的东西?

bvuwiixz

bvuwiixz1#

当我们有一个asp.net的核心MVC应用程序,它集成了微软的身份(使用模板创建项目并选择身份验证),我们将在页面的右上角有一个登录按钮。

它将有一个包含<a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignIn">Sign in</a>_LoginPartial.cshtml
所以/MicrosoftIdentity/Account/SignIn可能是你想要的。
我有一个测试,当我在浏览器中点击这个请求时,它会重定向到https://login.microsoftonline.com/tenant_id/oauth2/v2.0/authorize?client_id=xxx&redirect_uri=https://localhost:7245/signin-oidc&response_type=id_token&scope=openid%20profile&response_mode=form_post&nonce=xxx&client_info=1&x-client-brkrver=xx&x-client-SKU=ID_NETSTANDARD2_0&x-client-ver=6.15.1.0。我担心当你想使用它时,你可能需要为client-id, redirect-url and so on配置正确的变量。
我在program.cs和appsettings.json中有

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApp(builder.Configuration)

"AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "xxx",
    "TenantId": "xxx",
    "ClientId": "xx",
    "ClientSecret": "xxx",
    "CallbackPath": "/signin-oidc",
    "SignedOutCallbackPath ": "/signout-callback-oidc"
  },
dfuffjeb

dfuffjeb2#

我想我说的是正确的,如果不引入UI类和剃刀依赖项,这是不可能的。如果还有更简单的解决方案,我还没找到。
下面是我最终做的(使用一些简化的差异):
1.删除AzureADB2C:

--- a/Project.csproj
+++ b/Project.csproj
   <ItemGroup>
     <PackageReference Include="AutoMapper" Version="11.0.1" />
     <PackageReference Include="Azure.Storage.Blobs" Version="12.13.0" />
-    <PackageReference Include="Microsoft.AspNetCore.Authentication.AzureADB2C.UI" Version="6.0.6" />
+    <PackageReference Include="Microsoft.Identity.Web" Version="2.11.0" />
+    <PackageReference Include="Microsoft.Identity.Web.UI" Version="2.11.0" />
     <PackageReference Include="Npgsql" Version="6.0.4" />
     <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.4" />
     <PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.3.1" />

1.更新启动
这个练习的一部分目的是要摆脱这个丑陋的杂注,它抑制了关于AddAzureADB2C已过时的警告。我现在可以这样做:

--- a/Startup.cs
+++ b/Startup.cs
                  
-#pragma warning disable CS0618

替换身份验证架构代码:

return Task.CompletedTask;
                         }
                     };
-                    })
-                    .AddAzureADB2C(AzureADB2CDefaults.AuthenticationScheme, "AzureADB2COpenID", "AzureADB2CCookie", AzureADB2CDefaults.AuthenticationScheme, options =>
-                    {
-                        StartupValidator.B2cConfiguration.Bind(options);
                 });
 
+                services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
+                    .AddMicrosoftIdentityWebApp(options => {
+                        StartupValidator.B2cConfiguration.Bind(options);
+                        options.Events.OnTokenValidated = async context => {
+                            StartupValidator.BearerTokenDisplay = context.SecurityToken.RawData;
+                            await Task.CompletedTask;
+                        };
+                    })
+                    .EnableTokenAcquisitionToCallDownstreamApi()
+                    .AddInMemoryTokenCaches();
+
                 services.AddAuthorization(options =>
                 {
-                    var policyBuilder = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme, AzureADB2CDefaults.AuthenticationScheme);
+                    var policyBuilder = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme);
                     policyBuilder = policyBuilder.RequireAuthenticatedUser();
                     options.DefaultPolicy = policyBuilder.Build();
                 });
             }

这里的关键是到OnTokenValidated的钩子。之前,我使用一个claims阅读器扩展来拦截对signin链接回发的调用。原始代码调用b2clogin.com url,查询参数为response_type=id_token。这似乎不再可用了(它总是使用response_type=code),所以我不能在回发时获取auth令牌。
关于如何在身份验证后获得令牌的Microsoft文档绝对没有一个有效(例如here),这是这个过程中非常令人沮丧的一部分。最后我发现,您可以在令牌经过验证后挂钩到流中,并在那里获取它。不过,它只在“登录”回发后工作,所以它只在我的特定情况下有用,在生产环境中不起作用。最后,我将不得不发现为什么IAuthorizationHeaderProvider每次调用都会抛出异常,但不是今天。
最后,我需要添加razor页面和MS Identity UI,这样我就不必自己手工制作登录端点:

+            // razor pages are required to get signin link to work
+            services.AddRazorPages()
+                .AddMicrosoftIdentityUI();
 
             services
                 .AddControllers()

1.更新链接:

--- a/Homepage.cs
+++ b/Homepage.cs
         </p>
         <p style='padding-left:1.6em'>
-            <a href='/AzureADB2C/Account/SignIn/AzureADB2C'>Sign-in</a> |
-            <a href='/AzureADB2C/Account/SignOut/AzureADB2C'>Sign-out</a> |
-            <a href='/AzureADB2C/Account/EditProfile/AzureADB2C'>Edit Profile</a> |
-            <a href='/AzureADB2C/Account/ResetPassword/AzureADB2C'>Reset Password</a> |
+            <a href='/MicrosoftIdentity/Account/SignIn'>Sign-in</a> |
+            <a href='/MicrosoftIdentity/Account/SignOut'>Sign-out</a> |
         </p>
         <ul>

我现在可以使用登录链接来测试API,并根据需要复制粘贴承载令牌。

相关问题