Antti Alasvuo
Nov 10, 2020
(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.


  • 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.


  • can be done from Episerver Admin UI


  • 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.


  • 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


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.

    <!-- 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"/>

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.

    <!-- 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"/>

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">
        <remove roles="" users="*" verbs=""/>
        <add accessType="Allow" users="*" roles="*" verbs="GET"/>
<!-- allow anonymous users to get styles -->
<location path="App_Themes/Default/Styles">
        <remove roles="" users="*" verbs=""/>
        <add accessType="Allow" users="*" roles="*" verbs="GET"/>

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


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 SendGrid SMTP host is deprecated

SendGrid is a services for sending email that is included in Optimizely DXP. Previously was the recommended SMTP server to use,...

Tomas Hensrud Gulla | Dec 4, 2022 | Syndicated blog

Hosting Optimizely CMS 12 on Docker Engine

Since Optimizely CMS can now be deployed as a Docker container, here is a demonstration of building, running and scaling an Optimizely CMS 12 site ...

Stefan Holm Olsen | Dec 4, 2022 | Syndicated blog

How to use CacheTagHelper with content areas in Optimizely CMS 12

I might be going out on a limb here - if you have a better solution, feel very free to share it!  Upgrading your Optimizely web application from .N...

Andreas J | Dec 2, 2022

The 1001st Piece in your 1000 Piece Puzzle: .NET Default Interface Functions

I was recently working with a client who wanted a reasonably large subsystem added to Optimizely that would add automated management to their...

Greg J | Nov 28, 2022 | Syndicated blog

Video Demonstration, creating a CMS12 Alloy Sample Site

Hey All Below you will find a quick video demonstration on how to install a local version of Alloy Sample based on CMS12 / .Net 6. As you will see ...

Minesh Shah (Netcel) | Nov 28, 2022

Opticon Deep Dive: Optimizely's Product Announcements

We attended Opticon 2022 in San Diego which explored the future of orchestration, experimentation, and growth. We dive into Optimizely's product...

Liz Spranzani | Nov 28, 2022 | Syndicated blog