Skip to content

The protection doesn't work integrated with Identity Server #2

@erossini-chi

Description

@erossini-chi

I tried your code and it is working. I wanted to integrate the security with Identity Server and for this reason I changed Startup.cs like that (my folder under wwwroot is called infographics):

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.AddRazorPages(options => {
            options.Conventions.AuthorizePage("/Login");
        });

        services.Configure<IdentityServerConfiguration>(Configuration.GetSection("IdentityServerConfiguration"));

        services.AddDistributedMemoryCache();

        services.AddSession(options =>
        {
            options.Cookie.Name = ".my.Session";
            options.IdleTimeout = TimeSpan.FromHours(12);
        });

        services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = "oidc";
        })
        .AddCookie(options =>
        {
            options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
            options.Cookie.Name = "my.dashboard";
        })
        .AddOpenIdConnect("oidc", options =>
        {
            IdentityServerConfiguration idsrv = Configuration.GetSection("IdentityServerConfiguration").Get<IdentityServerConfiguration>();
            options.Authority = idsrv.Url;
            options.ClientId = idsrv.ClientId;
            options.ClientSecret = idsrv.ClientSecret;

            #if DEBUG
            options.RequireHttpsMetadata = false;
            #else
            options.RequireHttpsMetadata = true;
            #endif

            options.ResponseType = "code";

            options.Scope.Clear();
            options.Scope.Add("openid");
            options.Scope.Add("profile");
            options.Scope.Add("email");
            options.Scope.Add("roles");
            options.Scope.Add("offline_access");

            options.ClaimActions.MapJsonKey("role", "role", "role");

            options.GetClaimsFromUserInfoEndpoint = true;
            options.SaveTokens = true;

            options.SignedOutRedirectUri = "/";

            options.TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = JwtClaimTypes.Name,
                RoleClaimType = JwtClaimTypes.Role,
            };
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        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.UseAuthentication();

        app.UseStaticFiles(new StaticFileOptions
        {
            OnPrepareResponse = ctx =>
            {
                if (ctx.Context.Request.Path.StartsWithSegments("/infographics"))
                {
                    ctx.Context.Response.Headers.Add("Cache-Control", "no-store");

                    if (!ctx.Context.User.Identity.IsAuthenticated)
                    {
                        // respond HTTP 401 Unauthorized with empty body.
                        ctx.Context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                        ctx.Context.Response.ContentLength = 0;
                        ctx.Context.Response.Body = Stream.Null;

                        // - or, redirect to another page. -
                        // ctx.Context.Response.Redirect("/");
                    }
                }
            }
        });

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

I'm using the Login page to redirect the user to the Identity Server login page and then back.

After this changes, everybody can access to the files in the secret folder. Any idea why?
Thank you in advance.

Update

This is working with not HTML files. I think the problem comes from the HTML file because they are static content for ASP.NET.

I put a breakpoint on the OnPrepareResponse and call the page infographics/index.html. The page is displayed (red arrow) and then the application stops on the breakpoint (blue arrow).

image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions