在首次加载之前通过授权服务器保护 SPA [英] Securing a SPA by authorization server before first load

查看:24
本文介绍了在首次加载之前通过授权服务器保护 SPA的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 dotnet core 2.1 中使用新"项目模板用于 dotnet core 2.1 中的角度 SPA 应用程序,如文章

我的 Startup.cs:

public void ConfigureServices(IServiceCollection services){services.AddAuthentication(options =>{options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;options.DefaultChallengeScheme = "CustomScheme";}).AddCookie().AddOAuth("CustomScheme", options =>{//为简洁起见删除});services.AddMvc(config =>{//需要一个经过身份验证的用户var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().建造();config.Filters.Add(new AuthorizeFilter(policy));});//在生产中,Angular 文件将从这个目录提供services.AddSpaStaticFiles(configuration =>{configuration.RootPath = "ClientApp/dist";});}//这个方法被运行时调用.使用此方法配置 HTTP 请求管道.公共无效配置(IApplicationBuilder 应用程序,IHostingEnvironment 环境){如果 (env.IsDevelopment()){app.UseDeveloperExceptionPage();}别的{app.UseExceptionHandler("/Home/Error");}app.UseAuthentication();app.UseStaticFiles();app.UseSpaStaticFiles();app.UseMvc(routes =>{路线.MapRoute(名称:默认",模板:{controller=Home}/{action=Index}/{id?}");});app.UseSpa(spa =>{spa.Options.SourcePath = "ClientApp";如果 (env.IsDevelopment()){spa.UseAngularCliServer(npmScript: "start");}});}

当前行为:当我启动我的 SPA 时,由于 MVC 政策,我立即被重定向到我的授权服务器.身份验证成功后,我看到了家庭控制器的 Index 方法,但看不到我的 SPA.

所以问题是我从身份验证服务器重定向后应该如何为我的 SPA 提供服务?

解决方案

我有一些似乎有效的方法.

在我的研究中,我偶然发现了 这篇文章 建议使用中间件而不是 Authorize 属性.

现在,该 post authService 中使用的方法在我的情况下似乎不起作用(不知道为什么,我将继续调查并发布我稍后发现的任何内容).

所以我决定采用更简单的解决方案.这是我的配置

 app.Use(async (context, next) =>{如果(!context.User.Identity.IsAuthenticated){等待 context.ChallengeAsync("oidc");}别的{等待下一个();}});

在这种情况下,oidc 在 Spa 应用程序之前启动并且流程正常工作.根本不需要控制器.

HTH

I am using the 'new' project templates for angular SPA applications in dotnet core 2.1 as written in the article Use the Angular project template with ASP.NET Core.

But this article doesn't mention anything about securing the SPA itself. All information i find is about securing a WEBAPI but first of all i am interested in securing the SPA.

That means: When i open up my SPA e.g. https://localhost:44329/ i would like to be redirected to the authorization server immediatly instead of clicking some button that will do the authentication.

Background:

  • I have to ensure that only a authenticated users are allowed to see the SPA.
  • I want to use Authorization Code Grant to get refresh tokens from my authorization server.
  • I cannot use Implicit Grant because refresh tokens cannot be kept private on the browser

Current approach is to enforce a MVC policy that requires a authenticated user. But this can only be applied to a MVC Controller. That's why i added HomeController to serve the first request.

See project structure:

My Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = "CustomScheme";
        })
        .AddCookie()
        .AddOAuth("CustomScheme", options =>
        {
            // Removed for brevity
        });

    services.AddMvc(config =>
    {
        // Require a authenticated user
        var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();
        config.Filters.Add(new AuthorizeFilter(policy));
    });

    // In production, the Angular files will be served from this directory
    services.AddSpaStaticFiles(configuration =>
    {
        configuration.RootPath = "ClientApp/dist";
    });
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseAuthentication();

    app.UseStaticFiles();
    app.UseSpaStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });

    app.UseSpa(spa =>
    {
        spa.Options.SourcePath = "ClientApp";

        if (env.IsDevelopment())
        {
            spa.UseAngularCliServer(npmScript: "start");
        }
    });
}

Current behaviour: When i spin up my SPA i'm immediately redirected to my authorization server because of the MVC policy. After successful authentication i see the Index method of the home controller but not my SPA.

So the question is how should i serve my SPA after i have been redirected from authentication server?

解决方案

I have something that seems to work.

In my researches I stumbbled apon this post suggesting to use a middleware instead of the Authorize attribute.

Now, the method used in that post authService does not seem to work in my case (no clue why, I'll continue the investigation and post whaterver I find later on).

So I decided to go with a simpler solution. Here is my config

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

In this case, oidc kicks in BEFORE the Spa app and the flow is working properly. No need for a Controller at all.

HTH

这篇关于在首次加载之前通过授权服务器保护 SPA的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆