Monday, August 9, 2021

Redirect HTTP/HTTPS requests to a maintenance page using IIS with whitelisting some IPs

  Introduction

I was asked to show a maintenance page during the deployment for our website for a specific duration, at the same time, the website should be accessible for specific IPs for our development team to make the sanity check, once this is done, we should remove the maintenance page so the end-user can access the website again.

I googled a lot and I found some articles regarding applying this approach using some C# code, but I need something simple without writing any code or affecting our website.


The Idea

We will use the rewrite rule in IIS to redirect all traffic to the maintenance page, and at the same time, we will use it to allow specific IPs to access the website normally.

Steps

  1. Add the maintenance HTML page to your website root and name it #App_Offline.htm
    (If you removed the hashtag from the file name, that will force the website to "shut down" and display the content of the "App_Offline.htm" file itself, use this method if you don't want to whitelist specific IPs)


  2. Add the below XML to your website web.config file that is in your website folder (create it if this file is not there already)
     
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <system.webServer>
            <rewrite>
        <rules>
              <rule name="RequestBlockingDuringDowntime" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
              <match url="*" />
              <conditions logicalGrouping="MatchAll" trackAllCaptures="true">
                 <!-- IP1   -->
                <add input="{HTTP_X_FORWARDED_FOR}" pattern="156.215.114.99" negate="true" />
                <!--  IP2   -->
                <add input="{HTTP_X_FORWARDED_FOR}" pattern="156.219.163.72" negate="true" />
                <!--  IP3 -->
                <add input="{REMOTE_ADDR}" pattern="10.30.1.12" negate="true" />   
                 
              </conditions>
              <action type="Rewrite" url="#App_Offline.htm" />
          </rule>
        </rules>
      </rewrite>
        </system.webServer>
    </configuration>
     
     

Explanation

Any HTTP request has some headers that define the operating parameters for an HTTP transaction, from these headers, we're interested only in two of them, the REMOTE_ADDR which returns the IP address of the remote host making the request and the HTTP_X_FORWARDED_FOR which identifying the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer.

If the server that hosts your website is under a load balancer, then probably you will use HTTP_X_FORWARDED_FOR instead of REMOTE_ADDR 

Wednesday, February 10, 2021

Microsoft Dynamics CRM On-Premises | Find Security Role That Has a Certain Privilege


Introduction
Sometimes you will need to show all security roles that are using some privilege. I will show you how to do that using SQL for Microsoft Dynamics CRM On-Premises


Example
Select all security roles that have delete privilege

Code:

SELECT privilege . NAME [Privilege Name] ,
       role . NAME      [Security Role]
FROM   roleprivileges
       JOIN  privilege
         ON privilege . privilegeid =  roleprivileges . privilegeid
       LEFT JOIN  role
              ON role . roleid =  roleprivileges . roleid
WHERE  privilege . NAME LIKE '%delete%'   




That's useful if you're reviewing a big project and need to know for example who has the delete privilege for the account entity, then you can add this condition privilege.NAME LIKE '%account%' so the final SQL query will be as following

Code :


SELECT privilege . NAME [Privilege Name] ,
       role . NAME       [Security Role]
FROM   roleprivileges
       JOIN privilege
         ON  privilege . privilegeid = roleprivileges . privilegeid
       LEFT JOIN role
              ON role . roleid =  roleprivileges . roleid
WHERE  privilege . NAME LIKE  '%delete%'
       AND privilege . NAME LIKE  '%account%'