locked
Best way to implement a widget that can be used on another site (ASP.NET Core) RRS feed

  • Question

  • User571602223 posted

    Hello all,

    I have a task to implement a web site that has 3 pages and that can be used like a widget on another (autorized) site as well as on some tablet devices directly or in some widget-loading page.

    So I have to allow 2 types of access: xyz.com and a device.

    I started to develop a site where I have a url in a form of ".../Widget/GetWidget/apiKey". When the apiKey is validated, a session is loaded with some data used to continue to another page and to ensure that a session can be used a short period of time.

    Then I created a test html page with an iFrame to test a site. Then I came across problems with sessions in iFrames, inability to use a session cookie etc.

    Is there some another approach for implementing this kind of web site?

    Tuesday, December 8, 2020 9:38 PM

All replies

  • User475983607 posted

    vladimirpetrovic

    Is there some another approach for implementing this kind of web site?

    A JavaScript library that implements the widget UI and calls your site/service.

    Tuesday, December 8, 2020 10:08 PM
  • User-474980206 posted

    While it’s mire common to use JavaScript portals instead of iframes, you can still use an iframe, but you must follow the security rules. The site must be https and you need to set the cookie to samesite=none secure, when you create the cookie.

    https://docs.microsoft.com/en-us/aspnet/samesite/system-web-samesite

    Wednesday, December 9, 2020 3:44 PM
  • User571602223 posted

    Hello Bruce,

    I have already created a widget site (ASP.NET Core 3.1) to be used in iFrame put in some test html page and it works until I try to get data from a session. The session is empty. I have read some articles about this problem and I found that there are problems with using session cookie because of new security setup on browsers. 
    Here is my Startup.cs code where I try to make everything work:

    public void ConfigureServices(IServiceCollection services)
            {
                services.AddDistributedMemoryCache();
    
                services.AddSession(options =>
                {
                    options.IdleTimeout = TimeSpan.FromMinutes(10);
                    options.Cookie.HttpOnly = false;
                    options.Cookie.IsEssential = true;
                    options.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None;
                });
    
                services.AddMvc();
    
                services.AddControllersWithViews();
            }
    
            // 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("/Home/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.Use(async (context, next) =>
                {
                    context.Response.Headers.Remove("X-Frame-Options");
                    context.Response.Headers.Add("X-Frame-Options", "AllowAll");
                    await next();
                });
    
                app.UseRouting();
    
                app.UseAuthorization();
    
                app.UseSession();
                
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllerRoute(
                        name: "default",
                        pattern: "{controller=Widget}/{action=GetWidget}/{apiKey}");
                    endpoints.MapControllerRoute(
                        name: "default",
                        pattern: "{controller=Home}/{action=Index}/{id?}");
                });
            }

    Thursday, December 10, 2020 6:28 AM
  • User571602223 posted

    It seems that I had to add one more line to make this work:

    options.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.Always;

    There is a note in the article that says that a cookie has to be marked as secure.

    But I am wondering which approach is better and with less risk: JS or iFrame?

    Thursday, December 10, 2020 6:39 AM
  • User-474980206 posted

    It depends on the requirements. In the old days client code could resize the iframe to match the content size, but this is now a cross site scripting issue. also as browsers lock down 3rd party cookies you might run into issues in the future. I’d probably remove cookie requirements.


    Thursday, December 10, 2020 3:47 PM