2
votes

I have a React project inside a .NET core solution and basically I just want users to be authenticated to see the react project / SPA.

enter image description here

After doing a lot of investigating, it seems this is not possible without doing some code inside the React project which means adding security to the JS that can be manipulated in the client.

I have seen that it may be possible to authenticate on every request in .Net Core which might be the best way to go. Is this possible?

I have used some authentication code from other resources but I am getting errors. this is my startup.cs code

public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);



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


    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseAuthentication();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

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

        // This produces a server error.
        app.Use(async (context, next) =>
        {
            if (!context.User.Identity.IsAuthenticated)
            {
                await context.ChallengeAsync("");
            }
            else
            {
                await next();
            }
        });

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

            //routes.MapSpaFallbackRoute(
            //     name: "spa-fallback",
            //     defaults: new { controller = "Home", action = "AuthorizedSpaFallBack" });
        });

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

            if (env.IsDevelopment())
            {

                spa.UseReactDevelopmentServer(npmScript: "start");
            }
        });
    }
}

Or does anyone have any other ideas to achieve what I want?

Thanks

1
At a high level, what you need is JSON Web Token authentication for your API that the React front-end calls. You'll authenticate the user and issue a token for the front-end. The front-end then attaches that to all requests. The back-end API can then decide if the user should get access to the resource they are trying to access. Security must be based on the back-end. The front-end can also of course hide features and things the user can't use but that is in addition to authorization in the back-end.juunas

1 Answers

1
votes

If i understood you right, you want to authenticate users accessing the SPA using Backend authentication services. In that case you may resort to IdentityServer for that.

The link below demonstrates the use of API authorization with the combination of ASP.NET Core Identity for authenticating and storing users, and the IdentityServer for implementing OpenID Connect.

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity-api-authorization?view=aspnetcore-5.0