Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Securing a SPA by authorization server before first load

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:

enter image description here

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?

like image 211
Daniel Avatar asked May 08 '18 04:05

Daniel


People also ask

What is AddIdentityServerJwt?

The AddIdentityServerJwt method will configure the necessary pieces so that the IdentityServer application knows how to host the secure Web API and authentication service in the same web application. This step will be essential because the authentication server is usually a separate entity from the APIs it's securing.

How does .NET authorization work?

Authorization in ASP.NET Core is controlled with AuthorizeAttribute and its various parameters. In its most basic form, applying the [Authorize] attribute to a controller, action, or Razor Page, limits access to that component to authenticated users. Now only authenticated users can access the Logout function.

How do I authorize API in net core?

Require authorization on a new API By default, the system is configured to easily require authorization for new APIs. To do so, create a new controller and add the [Authorize] attribute to the controller class or to any action within the controller.

What can be used for authenticating the user in angular or react apps?

Your Angular application will redirect users to Auth0 whenever they trigger an authentication request. Auth0 will present them with the Universal Login page. Once they log in, Auth0 will redirect them to your application.


1 Answers

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

like image 127
Georges Legros Avatar answered Sep 24 '22 08:09

Georges Legros