【问题标题】:Want to add Hybrid Flow Authentication to the (dotnet) backend of a SPA想要将混合流身份验证添加到 SPA 的(dotnet)后端
【发布时间】:2018-12-25 02:32:01
【问题描述】:

我还没有看到任何关于如何向 SPA 应用程序添加身份验证的文档/示例,例如在 ASP.NET Core 2.1 上使用模板进行 react-redux 时(使用通常的 create-react-app 后面场景)。

澄清一下,我不是在问如何将隐式流身份验证添加到 React 客户端应用程序,我确实知道如何做到这一点,但这对我们的客户来说还不够安全。我希望后端(ASP.NET Core)使用混合流通过 OIDC 身份提供程序处理身份验证。

我正在向服务管道添加以下内容:

services.AddAuthentication(o =>
{
    o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    o.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, o =>;
{
    o.SlidingExpiration = bool.Parse(Configuration["SessionCookieSlidingEnabled"]);
    o.ExpireTimeSpan = TimeSpan.FromMinutes(int.Parse(Configuration["SessionCookieLifeTimeInMinutes"]));
    o.Cookie = new CookieBuilder { HttpOnly = true };
})
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, o =>
{
    o.Authority = Configuration["Authority"];
    o.ClientId = Configuration["OpenIdConnectOptions:ClientId"];
    o.ClientSecret = Configuration["OpenIdConnectOptions:ClientSecret"];
    o.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    o.GetClaimsFromUserInfoEndpoint = Convert.ToBoolean(Configuration["OpenIdConnectOptions:GetClaimsFromUserInfoEndpoint"]);
    o.RequireHttpsMetadata = Convert.ToBoolean(Configuration["OpenIdConnectOptions:RequireHttpsMetadata"]);
    o.ResponseType = Configuration["OpenIdConnectOptions:ResponseType"];
    o.SaveTokens = Convert.ToBoolean(Configuration["OpenIdConnectOptions:SaveTokens"]);
    o.UseTokenLifetime = false;
}

然后给configure方法对应app.UseAuthentication();

此外,我(未成功)尝试在 MVC 服务上配置全局过滤器,如下所示:

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

过去,我只是将 [Authorize] 过滤器附加到主控制器以触发流程,但显然自 2.1 以来,框架使用 SPA 中间件从 ClientApp 文件夹加载作为我的应用程序的入口点:

app.UseSpa(spa =>
{
    spa.Options.SourcePath = "ClientApp";
    if (env.IsDevelopment())
    {
        spa.UseReactDevelopmentServer(npmScript: "start");
    }
});

我的问题是:如何在没有控制器过滤器的情况下触发授权过程?

我已经针对 asp.net 核心文档创建了 this inquiry,我知道这不是 IdentityServer4 问题,但也许你们聪明的人可以对此事有所了解。

提前致谢。

【问题讨论】:

  • 在我看来,混合流根本不适合水疗。 github.com/IdentityModel/oidc-client-js/issues/405github.com/maxmantz/redux-oidc-example 证实了这一点,但是......看到新的东西会很有趣...... :)
  • @d_f 不,我完全明白,但我要求的是针对后端服务器执行混合流,然后 然后 在用户完成后加载 SPA成功登录,并拥有一个有效的 cookie。之后可能会对令牌使用静默刷新。
  • SPA 的想法是允许浏览器中的应用程序完全独立地工作,只需在需要的地方调用 API,这意味着应用程序中根本没有服务器端。混合流的思想是将浏览器和服务器分开,使用共同的clientId。但是为什么不将 SPA 和 API 分成不同的 oidc 客户端,允许 API 使用反向通道(据我了解,您的客户的要求)。
  • 完全正确。事实上,API 已经是一个单独的 ApiResource(oidc 客户端),并针对身份提供者服务器验证从 SPA 传递的访问/引用令牌。与其他网络应用程序一起工作就是如此!
  • 那么您真正需要的是使用 Authorize 属性保护一些静态文件(您的 spa 源)?这不是一个与 oidc 相关的问题。在这方面,我的第一个愚蠢的想法是不要使用静态,只需使用 MVC 索引视图来加载应用程序并执行身份验证预检查...

标签: c# asp.net-core react-redux single-page-application identityserver4


【解决方案1】:

用于 SPA 和任何其他静态中间件的 universal solution 是手动执行挑战,如下所示:

app.Use(async (context, next) =>
        {
            if (!context.User.Identity.IsAuthenticated)
            {
                await context.ChallengeAsync();
            }
            else
            {
                await next();
            }
        });

这个中间件应该在 Spa 和 Mvc 之前添加到链中。

【讨论】:

  • 这是完美的。我在森林里太深了,看不到简单的解决方案。现在我可以使用混合 OIDC 流并让 asp.net 中间件处理它。非常感谢。
  • 我刚刚开始以与您建议的方式相同的方式使用 .net core 3.1 react 模板。效果很好。我的问题是,如何在 React 应用程序中获取访问令牌?我需要它来向我的 api 服务发送请求吗?
  • @killjoy 我不是反应大师,但这个tutorial 一定是你需要的一种
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-26
  • 1970-01-01
  • 2017-01-13
  • 2011-11-04
  • 2018-08-11
  • 2021-04-23
  • 2015-07-18
相关资源
最近更新 更多