SaaS CMS has officially launched! Learn more now.

Antti Alasvuo
Nov 10, 2020
  1917
(2 votes)

How to protect you public test or stage environment from outsiders using authorization?

Sometimes we face a situation that we can't use maybe the more common/better ways to protect the test/stage environment by using IP-restrictions in web[dot]config (fyi, the blog platforms cloudflare security feature prevents using the dot in the file name :D) or in a load balancer or in a Web Application Firewall (WAF) or in a firewall or some other security feature. So is there then no other way? Yes there is - well at least we can make the resources not availabe if the user can't login in.

Background:

  • we havea public facing test and stage environment
  • we have people from all over the world with dynamic IP-addresses who should be able to see the content
    • they all have logins and different roles setup
    • ASP.NET Identity is used
  • we don't want "outsiders" to be able to see any resources from the website
  • excluding login and logout pages, these should be naturally accessible for anonymous users ;)

Solution one

Use Episerver 'Set Access Rights' and remove the 'Read' access from 'Everyone' group.

Pros:

  • can be done from Episerver Admin UI

Cons:

  • depending how access rights are used on the site, might require quite some clicking in the content tree to find all nodes which are not inheriting access rights from root
  • does not affect any static resources
  • does not affect any dynamic resources / programmatic resources not having authorization
  • when content is refreshed from production, this needs to be done again

Solution two

Use IIS security in web[dot]config file.

Pros:

  • can be done with a simple configuration transform for the target environment
  • content can be refreshed and no actions are needed, same restrictions are still in place
  • we can protect all resources from the website
  • well excluding the login and logout pages
  • no need to change the existing access rights for the content in Episerver

Cons:

None - Just kidding :D

  • it will not totally block access to the website for anonymous users, the login and logout pages are exposed
  • actually my below condifuration exposes anything below util path
  • because it will redirect to login when user is not logged in, if Episerver default login is used, it will expose the fact that the website is done with Episerver to the world
    • usually this is acceptable

web[dot]config configuration sample

So how to configure? Find in your web[dot]config file the root 'system.webServer' section and add the following or modify your existing element.

<security>
  <authorization>
    <!-- remove any exising users and roles -->
    <remove users="*" roles="" verbs=""/>
    <!-- add the roles that should be allowed to use the website after authentication -->
    <!-- now using the Episerver default groups which you need to change if you use something else -->
    <add accessType="Allow" users="" roles="WebAdmins,WebEditors"/>
  </authorization>
</security>

So the above will allow the selected groups/roles to access the website and if the request is not authorized the user will be redirected to the configured login url.

The above configuration blocks all requests so we need to allow anonymous requests (or requests that don't have the required roles to access the login page), so we need to add another configuration.

In your web[dot]config file find the location element for your login path (or add it if you are not using Episerver default login page). So the following configuration assumes you are using the default path which is under the 'util' path (if you have moved the util path to your-secret-util-path then you would apply the following change to that location element). Find the location element with path="util" and modify its system.webServer section.

Note! This is needed because we are not using Forms authentication but ASP.NET Identity, the authorization element has attribute 'bypassLoginPages' which defaults to true and would skip authorization for the loging page when using Forms authentication.

<security>
  <authorization>
    <!-- remove any previous configurations -->
    <remove roles="" users="*" verbs=""/>
    <!-- allow anonymous users -->
    <!-- and allow get and post verbs only -->
    <!-- get the page and post the login form -->
    <add accessType="Allow" users="*" roles="*" verbs="GET,POST"/>
  </authorization>
</security>

So after the above configurations the website should beonly accessible for 'authorized' users - so users who have logged in and have WebAdmins and/or WebEditors roles.

Tip! If you look at the login page request in browser developer tools network tab you will notice that there are some requests that have ended with 302 redirect to the login page. The login page works even without these resources and there seems to be no visible artifacts or missing functionality BUT if you want those requests to succeed you need to add two more location elements with allow configuration.

On the login page there are three requests to WebResource.axd and two requests to CSS style files under App_Themes/Default/Styles, so we can also allow those if we want to.

Add the following location elements to your web[dot]config file.

<!-- allow anonymous users to get the resources requested on util/login.aspx and logout.aspx-->
<location path="WebResource.axd">
  <system.webServer>
    <security>
      <authorization>
        <remove roles="" users="*" verbs=""/>
        <add accessType="Allow" users="*" roles="*" verbs="GET"/>
      </authorization>
    </security>
  </system.webServer>
</location>
<!-- allow anonymous users to get styles -->
<location path="App_Themes/Default/Styles">
  <system.webServer>
    <security>
      <authorization>
        <remove roles="" users="*" verbs=""/>
        <add accessType="Allow" users="*" roles="*" verbs="GET"/>
      </authorization>
    </security>
  </system.webServer>
</location>

All done!

Note, you should be able to also use the "system.web" section for the configuration but that is basically for old IIS and old Cassini development server ;)

See the IIS configuration reference for authorization.

Nov 10, 2020

Comments

Erik Henningson
Erik Henningson Nov 12, 2020 04:35 PM

Thanks for sharing Antti! I was just about to look into this kind of solution for a client who got tired of constantly updating the long list of ip-numbers, now that a lot of people are working from home :-)

Kane Made It
Kane Made It Nov 13, 2020 06:37 AM

Thanks for the post Antti. The authorization also comes in handy as it will prevent online search engines (SE)  from indexing the stage's page. Some user pushes content to stage first and incidentally SE indexes it. Afterward it is pushed to production page so SE like Google considers them as duplication. The authorization prevent SE from crawlings content, as well as other users.

Please login to comment.
Latest blogs
Optimizely release SaaS CMS

Discover the future of content management with Optimizely SaaS CMS. Enjoy seamless updates, reduced costs, and enhanced flexibility for developers...

Andy Blyth | Jul 17, 2024 | Syndicated blog

A day in the life of an Optimizely Developer - London Meetup 2024

Hello and welcome to another instalment of A Day In The Life Of An Optimizely Developer. Last night (11th July 2024) I was excited to have attended...

Graham Carr | Jul 16, 2024

Creating Custom Actors for Optimizely Forms

Optimizely Forms is a powerful tool for creating web forms for various purposes such as registrations, job applications, surveys, etc. By default,...

Nahid | Jul 16, 2024

Optimizely SaaS CMS Concepts and Terminologies

Whether you're a new user of Optimizely CMS or a veteran who have been through the evolution of it, the SaaS CMS is bringing some new concepts and...

Patrick Lam | Jul 15, 2024