Shinydocs Pro

Configure Shinydocs Pro Control Center for Azure Files (Azure file share)

What you are setting up

In this guide, you will be setting up an Azure Files source in Shinydocs Pro for analysis and setting up the connection for permission checking of Search results for your source.

Once complete:

  • Your Azure Files source will be analyzed by Shinydocs Pro

  • Files are immediately searchable via Search, enforcing Azure Files permissions on all search results.

Requirements

  • Shinydocs Pro is installed and running.

  • Internet access to reach Microsoft Online

    • If the server cannot have direct internet access, ensure firewall rules are setup to allow HTTPS traffic on port 443

  • Azure/Entra permission to:

    • Create application registrations

    • Grant admin consent

    • Permission to see and modify your storage account

  • A certificate used to authenticate (Azure requires the .cer and Shinydocs Pro requires the .pfx)

Create the self signed certificate for Azure

If you already have a process internally for creating these certificates, please follow your organizations best practices. If not, you can use the script below.

PowerShell script for certificate generation

This script is from Microsoft (https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread)

Save this script in notepad as GenerateCertificate.ps1

PowerShell
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Creates a Self Signed Certificate for use in server to server authentication
.DESCRIPTION
.EXAMPLE
.\Create-SelfSignedCertificate.ps1 -CommonName "MyCert" -StartDate 2015-11-21 -EndDate 2017-11-21
This will create a new self signed certificate with the common name "CN=MyCert". During creation you will be asked to provide a password to protect the private key.
.EXAMPLE
.\Create-SelfSignedCertificate.ps1 -CommonName "MyCert" -StartDate 2015-11-21 -EndDate 2017-11-21 -Password (ConvertTo-SecureString -String "MyPassword" -AsPlainText -Force)
This will create a new self signed certificate with the common name "CN=MyCert". The password as specified in the Password parameter will be used to protect the private key
.EXAMPLE
.\Create-SelfSignedCertificate.ps1 -CommonName "MyCert" -StartDate 2015-11-21 -EndDate 2017-11-21 -Force
This will create a new self signed certificate with the common name "CN=MyCert". During creation you will be asked to provide a password to protect the private key. If there is already a certificate with the common name you specified, it will be removed first.
#>
Param(

[Parameter(Mandatory=$true)]
   [string]$CommonName,

[Parameter(Mandatory=$true)]
   [DateTime]$StartDate,

[Parameter(Mandatory=$true)]
   [DateTime]$EndDate,

[Parameter(Mandatory=$false, HelpMessage="Will overwrite existing certificates")]
   [Switch]$Force,

[Parameter(Mandatory=$false)]
   [SecureString]$Password
)

# DO NOT MODIFY BELOW

function CreateSelfSignedCertificate(){

#Remove and existing certificates with the same common name from personal and root stores
    #Need to be very wary of this as could break something
    if($CommonName.ToLower().StartsWith("cn="))
    {
        # Remove CN from common name
        $CommonName = $CommonName.Substring(3)
    }
    $certs = Get-ChildItem -Path Cert:\LocalMachine\my | Where-Object{$_.Subject -eq "CN=$CommonName"}
    if($certs -ne $null -and $certs.Length -gt 0)
    {
        if($Force)
        {

foreach($c in $certs)
            {
                remove-item $c.PSPath
            }
        } else {
            Write-Host -ForegroundColor Red "One or more certificates with the same common name (CN=$CommonName) are already located in the local certificate store. Use -Force to remove them";
            return $false
        }
    }

$name = new-object -com "X509Enrollment.CX500DistinguishedName.1"
    $name.Encode("CN=$CommonName", 0)

$key = new-object -com "X509Enrollment.CX509PrivateKey.1"
    $key.ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
    $key.KeySpec = 1
    $key.Length = 2048
    $key.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)"
    $key.MachineContext = 1
    $key.ExportPolicy = 1 # This is required to allow the private key to be exported
    $key.Create()

$serverauthoid = new-object -com "X509Enrollment.CObjectId.1"
    $serverauthoid.InitializeFromValue("1.3.6.1.5.5.7.3.1") # Server Authentication
    $ekuoids = new-object -com "X509Enrollment.CObjectIds.1"
    $ekuoids.add($serverauthoid)
    $ekuext = new-object -com "X509Enrollment.CX509ExtensionEnhancedKeyUsage.1"
    $ekuext.InitializeEncode($ekuoids)

$cert = new-object -com "X509Enrollment.CX509CertificateRequestCertificate.1"
    $cert.InitializeFromPrivateKey(2, $key, "")
    $cert.Subject = $name
    $cert.Issuer = $cert.Subject
    $cert.NotBefore = $StartDate
    $cert.NotAfter = $EndDate
    $cert.X509Extensions.Add($ekuext)
    $cert.Encode()

$enrollment = new-object -com "X509Enrollment.CX509Enrollment.1"
    $enrollment.InitializeFromRequest($cert)
    $certdata = $enrollment.CreateRequest(0)
    $enrollment.InstallResponse(2, $certdata, 0, "")
    return $true
}

function ExportPFXFile()
{
    if($CommonName.ToLower().StartsWith("cn="))
    {
        # Remove CN from common name
        $CommonName = $CommonName.Substring(3)
    }
    if($Password -eq $null)
    {
        $Password = Read-Host -Prompt "Enter Password to protect private key" -AsSecureString
    }
    $cert = Get-ChildItem -Path Cert:\LocalMachine\my | where-object{$_.Subject -eq "CN=$CommonName"}

Export-PfxCertificate -Cert $cert -Password $Password -FilePath "$($CommonName).pfx"
    Export-Certificate -Cert $cert -Type CERT -FilePath "$CommonName.cer"
}

function RemoveCertsFromStore()
{
    # Once the certificates have been been exported we can safely remove them from the store
    if($CommonName.ToLower().StartsWith("cn="))
    {
        # Remove CN from common name
        $CommonName = $CommonName.Substring(3)
    }
    $certs = Get-ChildItem -Path Cert:\LocalMachine\my | Where-Object{$_.Subject -eq "CN=$CommonName"}
    foreach($c in $certs)
    {
        remove-item $c.PSPath
    }
}

if(CreateSelfSignedCertificate)
{
    ExportPFXFile
    RemoveCertsFromStore
}

Run the script:

  1. Open PowerShell as administrator.

  2. Navigate to the directory you saved the script to. (cd)

  3. Run the script by entering .\GenerateCertificate.ps1

  4. Follow the prompts in the console to generate the certificate for Azure

Step 1 - Register Shinydocs Software with Azure

The first step of the process is to register your Shinydocs software with Azure, so that it can access Azure Files data.

You only need to register one application for Shinydocs software. Permissions to supported repositories can be configured the one registration.

  1. Open Microsoft Azure.

  2. In the upper left corner dropdown menu, navigate to Azure Active Directory.

    AAD.PNG
  3. From the sidebar menu, select App registrations

    app registrations.PNG
  4. Select + New registration

    Register Azure.PNG
  5. Enter a name for the application. In this case, we used “Shinydocs Pro” as the application name.

  6. Select who, within your organization, can use or access the application. In most cases, the first option (Single tenant) will be selected (see below).

  7. The optional Redirect URl is not needed in this case.

  8. Select Register to continue.

    register.PNG

Upload Authentication Certificate to Azure

These steps require a .cer file.

  1. From the sidebar menu, select Certificates & secrets

  2. Select Certificates

  3. Select Upload certificate

    image-20230608-151530.png
  4. Select the folder icon to browse for your certificate (.cer). Optionally, add a description to let other administrators know what this certificate is used for.

    image-20230608-151912.png
  5. Select Add

  6. Verify that the certificate was uploaded successfully by confirming the certificate is shown Certificates

    image-20230608-152201.png
  7. Still in Certificates & secrets, click the Client secrets tab.

  8. Click + New client secret

    1. In the Add a client secret panel, add a description of your choice

    2. Set it to expire in 12 months or longer.
      This is a good time to schedule a reminder for the expiry, as Shinydocs Pro will also need the new secret key when this one expires.

    3. Click Add.

    4. Copy the secret key to a safe location, as you will not be able to retrieve it later.

  9. In the left-hand menu, open Overview

  10. Note/save the following information for configuring Shinydocs Pro in later steps.

  • Application (client) ID: ___________________________________________________
  • Directory (tenant) ID: ___________________________________________________
  • Secret key: ___________________________________________________

Authentication

Still in the Azure portal Shinydocs application registration, now you will set up the redirect URIs for authentication.

  1. Navigate to the Authentication tab in the application registration

    image-20251010-160550.png
  2. Web > Redirect URIs

    1. This set up will be for the server running Shinydocs Pro Search using it’s hostname. You can update these settings later when/if you set up your fully qualified domain name in your DNS.

    2. Redirect URIs (Web platform):

      1. https://<shinydocs pro server host name>:9701/oauth/authorized

        1. e.g. https://shinyvm:9701/oauth/authorized

        2. If users reach Control Center by its full domain name, add that as well, e.g. https://shinyvm.contoso.com:9701/oauth/authorized

      2. https://localhost:9701/oauth/authorized

      Each URI must exactly match the source’s Redirect URL with /oauth/authorized added. Include the port, unless your DNS or proxy removes it.

Step 2 - Assign the Roles to the Service Principal

When an application registration is performed in Azure, a Service Principal is automatically created for it. In this step, you will be assigning the appropriate roles for it to access Azure Files.

  1. In the Azure portal, navigate to the Storage account section in your tenant

    image-20260312-190206.png
  1. Select Access Control (IAM) from the sidebar.

    image-20260312-190241.png
  1. Click Add, then select Add role assignment.

  1. Search for and select one or both depending on what you want Shinydocs Pro to be able to do:

    image-20260312-195740.png


    1. Storage File Data Privileged Contributor
      You want to analyze your content and action it (i.e. disposal)

    2. Storage File Data Privileged Reader
      You only want to analyze data and not action it (i.e. disposal)

  1. Under Members, select User, group, or service principal.

  1. Search for and select your Shinydocs App Registration by name.

  1. Click Review + assign.

Step 3 - Azure API Permissions Configuration (for Search functionality)

Now that the Shinydocs Application has been registered with Azure, it’s time to apply permissions to access content within Azure Files.

  1. From the sidebar menu, select API permissions

    API perms.PNG
  2. Select + Add a permission

    image-20240506-141546.png
  3. Select Microsoft Graph:

    image-20241016-181749.png
  4. Then, select Delegated permissions

    image-20251010-162843.png
  5. Add the following delegated permissions

    1. User.Read
      Type: Delegated

    2. offline_acccess
      Type: Delegated

    3. openid
      Type: Delegated

    4. profile
      Type: Delegated

  6. Click Add permissions

  7. Select + Add a permission again

  8. Select APIs my organization uses and search for Azure Storage

    image-20260730-182333.png
  9. Then, select Delegated permissions and check the box for user_impersonation

    image-20260730-182442.png
  10. Click add permissions.

  11. Select Grant admin consent for [tenant], confirm when prompted

Step 4 - Add your Azure Files source in Shinydocs Pro Control Center

You need the .pfx certificate file you created earlier.

  1. In Shinydocs Pro Control Center, select Add source. It is on the Overview page and the Sources page.

  2. On the New tab, select Azure Files, then select Next. To add another source to a Azure Files connection you already set up, use the Existing tab instead.

    cc-src-26-5-picker.png
  3. Fill out the form with the details from your app registration:

    cc-src-26-5-azure-files-connection.png
    • Connection name: leave as is, or enter a name of your own.

    • Service Uri: replace storageAccountName with the name of your Azure storage account, for example https://azslfiletest.file.core.windows.net.

    • Share Name: the name of the Azure file share you want to analyze.

    • Application ID: the Application (client) ID you noted.

    • Tenant ID: the Directory (tenant) ID you noted.

    • Certificate file: select Choose File and upload your .pfx file. The certificate is stored with the connection, so moving the file afterwards doesn’t affect it.

    • Certificate password (optional): the password for the .pfx file. Leave it blank if the file has no password.

    • Search Authentication Type: select Protected - OAuth2, then fill in:

      cc-src-26-5-auth-azure-files-protected-oauth2.png
      • Client Id: the Application (client) ID from your app registration.

      • Client Secret: the client secret from your app registration.

      • Login/Authorize Endpoint and Token Endpoint: replace common with your Tenant ID, for example https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize and .../oauth2/v2.0/token.

      • Redirect URL: the address users reach Shinydocs Search on, as domain and port only, for example https://search.contoso.com:9701. https://localhost:9701 works for testing on the server itself. /oauth/authorized is added automatically. This URL with /oauth/authorized must match a redirect URI on the app registration in Microsoft Entra ID exactly.

  4. Select Next. Control Center checks the connection before you continue. If something is wrong, the error says which setting to fix. A source can only be added while an agent is online.

  5. Choose the scope of the analysis. Enter the folder path exactly as it appears in your file share, relative to the share root. Use a forward slash ( / ) to separate nested folders, and don’t include the share name or a leading slash.

    Paths are case-sensitive. If a path is not found, you see an error before the crawl begins. Select Add for another folder, or Add multiple to paste several paths, one per line. Each path is crawled as its own root, and only those folders (and their subfolders) are indexed. If two folders share a name in different locations, use the full path.

  6. Optionally, select More options to set the Schedule (Daily or None), then select Return.

    cc-src-26-5-schedule.png
  7. Select Start analysis.

The new source runs the analysis set for Azure Files connections under Settings > Analysis. To change what runs for this source, or its schedule, open it from the Sources page. See Shinydocs Pro Control Center Guide.

Before publishing: Step 1 > Authentication lists the redirect URIs /azuread/success and /api/v1/oidc/signin-callback, but Protected - OAuth2 search sign-in uses <Redirect URL>/oauth/authorized (with the port). Add that URI to Step 1, as on the Microsoft sources page.