【问题标题】:How do you create a API/IdentityServer/Blazor(server-side) application?如何创建 API/IdentityServer/Blazor(服务器端)应用程序?
【发布时间】:2019-12-02 00:18:12
【问题描述】:

我尝试自己构建此应用程序,但在此过程中遇到了几个绊脚石。我认为最好退后一步,更深入地了解我正在尝试创建的内容。似乎没有任何关于如何制作我正在寻找的东西的文档。 (除非有人能指出我可能错过的正确位置)

我最终想要的是让 Blazor(服务器端)应用程序进行 API 调用以使用应用程序中的数据,然后让 IdentityServer4 封装身份验证。我需要 Azure 和 ASP.net Identity 作为可能的身份验证方法。

我已经尝试过并且能够创建一个也具有本地 API 的 IdentityServer4。我可以从邮递员那里打电话来获取令牌等。但是,当谈到将 Blazor(服务器端)应用程序绑定到 IdentityServer4 时,我感到很困惑。

我试图具体地问这个问题,但根本没有得到任何结果。我希望这个更大的视角可能会有所帮助。

似乎 odic-client.js 是从 IdentityServer4 回调中获取数据的方式,但是,这似乎与 Blazor(服务器端)中的 .NET 授权不太匹配。我如何让它们一起工作。

【问题讨论】:

    标签: identityserver4 blazor-server-side asp.net-core-3.0


    【解决方案1】:

    重要提示:现在有比我的回答更好的来源。按照此答案最后部分提供的链接进行操作。

    我使用 API / IdentityServer4 / Blazor(服务器端)进行了类似的设置。我给你看一些我使用的代码,也许你可以利用它。

    使用 NuGet 包 Microsoft.AspNetCore.Authentication.OpenIdConnect,我在 Startup 类的 ConfigureServices 方法中得到了这段代码:

            services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";
            })
            .AddCookie("Cookies")
            .AddOpenIdConnect("oidc", options =>
            {
                options.Authority = "https://localhost:5001";
    
                options.ClientId = "myClient";
                options.ClientSecret = "mySecret";
                options.ResponseType = "code id_token";
    
                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;
    
                options.Scope.Add("MyApi");
                options.Scope.Add("offline_access");
    
                options.ClaimActions.MapJsonKey("website", "website");
            });
    

    在配置方法app.UseAuthentication();

    然后在 App.razor 中我使用了 CascadingAuthenticationState 组件:

    <CascadingAuthenticationState>
         <Router AppAssembly="typeof(Startup).Assembly" />
    </CascadingAuthenticationState>
    

    并在我的主页 Index.razor 中使用 NuGet 包 Microsoft.AspNetCore.Authorization:

    @using Microsoft.AspNetCore.Authorization
    @attribute [Authorize]
    

    现在,当您打开主页时,它应该显示“未通过身份验证”,但仍然没有重定向到 IdentityServer4。为此,您还必须在启动时添加 MVC,正如我从 this stackoverflow question 学到的那样:

            services.AddMvcCore(options =>
            {
                var policy = new AuthorizationPolicyBuilder()
                    .RequireAuthenticatedUser()
                    .Build();
                options.Filters.Add(new AuthorizeFilter(policy));
            });
    

    现在您应该会在启动应用程序后被重定向到 IdentityServer4 以登录。就我而言,我有一个 ApiClient,它描述了我的 API 的方法。我使用 DI 注入 ApiClient 并添加访问令牌:

            services.AddHttpClient<IApiClient, ApiClient>(async (serviceProvider, client) =>
            {
                var httpContextAccessor = serviceProvider.GetService<IHttpContextAccessor>();
    
                var accessToken = await httpContextAccessor.HttpContext.GetTokenAsync("access_token");
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
    
                client.BaseAddress = new Uri("http://localhost:55578");
            });
    

    就像你说的,除了 stackoverflow 上的一些答案外,没有太多关于这个主题的文档。我花了很长时间来设置它,所以我希望我能在这篇文章中帮助其他人。

    更新:注销过程

    使用此设置注销需要绕行到 razor 页面,因为在加载 blazor 组件后无法访问 HttpContext。

    在Pages文件夹中新建一个Razor页面,在新创建的Logout.cshtml.cs中添加如下代码:

    public class LogoutModel : PageModel
    {
        public async void OnGetAsync()
        {
            await HttpContext.SignOutAsync("Cookies");
            var prop = new AuthenticationProperties()
            {
                RedirectUri = "http://localhost:62909"
            };
            await HttpContext.SignOutAsync("oidc", prop);
        }
    }
    

    在某处添加一个注销按钮,该按钮调用函数UriHelper.NavigateTo("/Logout"),依赖于@inject IUriHelper UriHelper。完成!

    更新:登录解决方法

    前面描述的登录过程在本地工作,但在发布到测试服务器后,我遇到了问题,IHttpContextAccessorAddHttpClient 方法中始终为空。所以我最终使用了与注销过程相同的解决方法。我让 IdentityServer 重定向到一个剃须刀页面(它总是有一个 HttpContext),将访问令牌保存在用户声明中并重定向到索引页面。在AddHttpClient 方法中,我只从用户声明中获取令牌并将其放入身份验证标头中。

    更新:未解决的问题

    我仍然很难让这个设置在我们的服务器上运行。我在 AspNetCore Github 上打开了 issuerequirement,但都在没有正确答案的情况下关闭了。目前,我发现一些博客可以很好地概述该主题的当前状态: https://mcguirev10.com/2019/12/15/blazor-authentication-with-openid-connect.html https://wellsb.com/csharp/aspnet/blazor-consume-identityserver4-protected-api/

    【讨论】:

    • 哇,这段代码终于有了!与您的原始帖子一样长,我一直在努力解决此问题。终于有了适合我想做的事情的东西真是太棒了。我希望其他人找到这篇文章并将其用作解决方案!
    • 如何在此设置中添加注销?
    • 我还没有添加注销,但我计划在接下来的几天内执行此操作。完成后我会通知你的。
    • 在注销过程中运气好吗?
    • 另一个需要注意的问题是,一旦 Blazor 切换到 SignalR 连接,应用到登录的任何过期都将被忽略。不幸的是,Blazor 身份验证故事现在处于非常悲惨的状态。我真的很生气 github 机器人关闭了由@PascalR 发起的问题。
    【解决方案2】:

    【讨论】:

      猜你喜欢
      • 2020-09-18
      • 2021-10-21
      • 2023-01-05
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-18
      • 2020-12-18
      相关资源
      最近更新 更多