Sitecore AAD user can't elevated unlock item | sitecore Elevated Unlock not working

Login Sitecore with Azure Active Directory can't elevated unlock item

Refer to

https://www.altudo.co/resources/blogs/azuread-setup-for-sitecore

Question

AAD user can't elevated unlock sitecore item, sitecore local user is working normally.
When AAD user click the Elevated Unlock button , it's refresh the page ,but not unlock item.
https://s1.ax1x.com/2022/05/17/O541jH.png

Info

  • Elevated Unlock is a powershell script of Sitecore SPE module.

Scripts Item

1.Elevated Unlock
item path: /sitecore/system/Modules/PowerShell/Script Library/SPE/Tools/Security Management/Content Editor/Warning/Elevated Unlock

$item = Get-Item -Path "."

$rules = $PSScript.Fields["EnableRule"].Value

$isEnabled = Test-Rule -InputObject $item -Rule $rules -RuleDatabase "master"
if(!$isEnabled) {
    exit
}


$icon = "Office/16x16/lock_open.png"
$source = [Sitecore.Resources.Images]::GetThemedImageSource($icon)

$title = "Elevated Unlock"
$text = "<img src='$($source)' />Use elevated privileges to unlock the current item."

$warning = $pipelineArgs.Add()
$warning.Title = $title
$warning.Text = $text

$script = Get-Item -Path "master:" -ID "{BD07C7D1-700D-450C-B79B-8526C6643BF3}"
$command = "item:executescript(id=$($item.ID),db=$($item.Database.Name),script=$($script.ID),scriptDb=$($script.Database.Name))"
$warning.AddOption("Unlock", $command)
$warning.HideFields = $false

this button can showing on item , meaning the powershell script is working normally.

2.Unlock Item
item path: /sitecore/system/Modules/PowerShell/Script Library/SPE/Tools/Security Management/Development/Unlock Item

$user = Get-User -Id "sitecore\admin"
New-UsingBlock (New-Object Sitecore.Security.Accounts.UserSwitcher $user) {
    Get-Item -Path . | Unlock-Item
}
Close-Window

this script meaning use Admin account to unlock the item.

Analyize

1.Write log
Use Write-Log command write some log to SPE.log(/App_Data/Logs/SPE.log.xxxx)
Found the Elevated Unlock script is running normal, but Unlock Item script is not running.
So check item:executescript command,

<command name="item:executescript" type="Spe.Client.Commands.MenuItems.ExecutePowerShellScript,Spe" patch:source="Spe.config"/>

2.Debug with dotpeek
https://s1.ax1x.com/2022/05/17/O5425V.png
found xmlcontrol=PowerShellRunner
url: https://sc.local/sitecore/shell/default.aspx?xmlcontrol=PowerShellRunner

3.Test
AAD user can't open this link, it will redirect to login page. It's same when AAD user click that button , the page will refresh.

4.Continue, find all xml control from sitecore config

<controlSources>
    <source folder="/sitecore/shell/override" namespace="Sitecore.Web.UI.XmlControls" mode="on" deep="true"/>
    <source folder="/layouts" namespace="Sitecore.Web.UI.XmlControls" mode="on" deep="false"/>
    <source folder="/sitecore/shell/controls" namespace="Sitecore.Web.UI.XmlControls" mode="on" deep="true"/>
    <source folder="/sitecore/shell/applications" namespace="Sitecore.Web.UI.XmlControls" mode="on" deep="true"/>
    <source folder="/sitecore modules" namespace="Sitecore.Web.UI.XmlControls" mode="on" deep="true"/>
    <source assembly="Sitecore.Kernel" namespace="Sitecore.Web.UI.HtmlControls" mode="on"/>
    <source assembly="Sitecore.Kernel" namespace="Sitecore.Web.UI.WebControls" mode="on"/>
    <source assembly="Sitecore.Kernel" namespace="Sitecore.Shell.Web.UI.WebControls" prefix="shell" mode="on"/>
    <source assembly="Sitecore.Kernel" namespace="Sitecore.Shell.Applications.ContentEditor" prefix="content" mode="on"/>
    <source assembly="Sitecore.Kernel" namespace="Sitecore.Shell.Web.Applications.ContentEditor" prefix="shell" mode="on"/>
    <source assembly="Sitecore.Kernel" namespace="Sitecore.WebControls" mode="on"/>
    <source assembly="System.Web" namespace="System.Web.UI.WebControls" prefix="asp" mode="on"/>
    <source assembly="System.Web" namespace="System.Web.UI.HtmlControls" prefix="html" mode="on"/>
    <source assembly="Sitecore.Kernel" namespace="Sitecore.Web.UI.Portal" mode="on"/>
    <source assembly="ComponentArt.Web.UI" namespace="ComponentArt.Web.UI" prefix="ca" mode="on"/>
    <source assembly="Sitecore.Buckets" namespace="Sitecore.Buckets.FieldTypes" prefix="contentExtension" mode="on" patch:source="Sitecore.Buckets.config"/>
    <source assembly="Sitecore.Buckets" namespace="Sitecore.Buckets.Controls" mode="on" patch:source="Sitecore.Buckets.config"/>
    <source folder="/sitecore modules/shell/emailcampaign" namespace="Sitecore.Modules.EmailCampaign.XmlControls" prefix="EmailCampaign" mode="on" deep="true" patch:source="Sitecore.EmailExperience.UI.config"/>
    <source assembly="Sitecore.EmailCampaign.Cm.UI" namespace="Sitecore.Modules.EmailCampaign.UI.Controls" prefix="EmailCampaign" mode="on" patch:source="Sitecore.EmailExperience.UI.config"/>
    <source assembly="Sitecore.EmailCampaign.Cm.UI" namespace="Sitecore.Modules.EmailCampaign.UI.HtmlControls" mode="on" patch:source="Sitecore.EmailExperience.UI.config"/>
    <source assembly="Sitecore.Scientist.Foundation.Fields" namespace="Sitecore.Scientist.Foundation.Fields.ContentEditor.Controls" prefix="custom" mode="on" patch:source="Sitecore.Scientist.Foundation.Fields.CustomNameValueList.config"/>
    <source assembly="Spe" namespace="Spe.Client.Controls" mode="on" patch:source="Spe.config"/>
    <source folder="/sitecore modules/Shell/PowerShell/" namespace="Spe.Client.Applications" mode="on" deep="true" patch:source="Spe.config"/>
</controlSources>

5.The last one Spe.Client.Applications
found the PowerShellRunner class and Onload events check the premission.
https://s1.ax1x.com/2022/05/17/O54j2D.png

6.TerminateUnauthorizedRequest

protected override void OnLoad(EventArgs e)
    {
      if (ServiceAuthorizationManager.TerminateUnauthorizedRequest("execution", Context.User?.Name))
      {
        PowerShellLog.Warn("User " + Context.User?.Name + " attempt to access PowerShell Script Runner Dialog - denied.");
      }
      else
      {
....

7.If user not authorized and will redirect to login page.

 public static bool TerminateUnauthorizedRequest(string serviceName, string userName = null)
    {
      if (ServiceAuthorizationManager.IsUserAuthorized(serviceName, userName))
        return false;
      if (HttpContext.Current != null && Context.Site != null)
        HttpContext.Current.Response.Redirect(Context.Site.LoginPage, true);
      return true;
    }

8.IsUserAuthorized

public static bool IsUserAuthorized(string serviceName, string userName = null)
    {
      if (!WebServiceSettings.IsEnabled(serviceName))
        return false;
      List<AuthorizationEntry> authorizationInfo = ServiceAuthorizationManager.GetServiceAuthorizationInfo(serviceName);
      string authorizationCacheKey = ServiceAuthorizationManager.GetAuthorizationCacheKey(serviceName, userName);
      if (string.IsNullOrEmpty(userName))
        return false;
      if (ServiceAuthorizationManager.ExistsInCache(authorizationCacheKey))
      {
        lock (ServiceAuthorizationManager._authorizationCache)
          return ServiceAuthorizationManager._authorizationCache[authorizationCacheKey].Authorized;
      }
      else
      {
        bool? nullable1 = new bool?();
        bool? nullable2 = new bool?();
        User user = User.FromName(userName, false);
        foreach (AuthorizationEntry authorizationEntry in authorizationInfo)
        {
          switch (authorizationEntry.IdentityType)
          {
            case AccountType.Role:
              Role identity = (Role) authorizationEntry.Identity;
              if ((!nullable1.HasValue || nullable1.Value) && ((Account) identity != (Account) null && user.IsInRole(identity) || "sitecore\\IsAdministrator".Equals(authorizationEntry.Identity.Name, StringComparison.InvariantCultureIgnoreCase) && user.IsAdministrator))
              {
                nullable1 = new bool?(authorizationEntry.AccessPermission == AccessPermission.Allow);
                break;
              }
              break;
            case AccountType.User:
              if ((!nullable2.HasValue || nullable2.Value) && authorizationEntry.WildcardMatch(userName))
              {
                nullable2 = new bool?(authorizationEntry.AccessPermission == AccessPermission.Allow);
                if (nullable2.Value)
                  break;
                break;
              }
              break;
          }
        }
        bool flag = false;
        if (nullable2.HasValue)
          flag = nullable2.Value;
        else if (nullable1.HasValue)
          flag = nullable1.Value;
        lock (ServiceAuthorizationManager._authorizationCache)
          ServiceAuthorizationManager._authorizationCache[authorizationCacheKey] = new AuthCacheEntry()
          {
            Authorized = flag,
            ExpirationDate = DateTime.Now.AddSeconds((double) WebServiceSettings.AuthorizationCacheExpirationSecs)
          };
        return flag;
      }
    }

9.The 6 step indicate the service is execution, search it in config

<execution enabled="true" requireSecureConnection="false">
    <authorization>
        <add Permission="Allow" IdentityType="Role" Identity="sitecore\Sitecore Client Users"/>
        <!--  "Magic" role that catches all users in Sitecore with Administrator privileges  -->
        <add Permission="Allow" IdentityType="Role" Identity="sitecore\IsAdministrator"/>
    </authorization>
</execution>

10.Finally
we found the page https://sc.local/sitecore/shell/default.aspx?xmlcontrol=PowerShellRunner require user belong to sitecore\Sitecore Client Users or sitecore\IsAdministrator
but the AAD user can't see the memberof, so the AAD can't Elevated Unlock Item.
https://s1.ax1x.com/2022/05/17/O55pqA.png

Result

  1. We can add the sitecore\Sitecore Client Users to user group manualy
    https://s1.ax1x.com/2022/05/17/O55Pat.png
  2. Update sitecore config , allow all user run that xmlcontrol
<add Permission="Allow" IdentityType="User" Identity="*" />

评论

还没有人评论,抢个沙发吧...

Viagle Blog

欢迎来到我的个人博客网站