UserExtensions静态类在开发配置中工作,但不适用于发布/生产

时间:2018-03-26 18:06:53

标签: .net asp.net-core

我配置了一个静态类来扩展ClaimsPrincipal静态类和一个SystemRoles静态类,以声明要在整个应用程序中使用的组/角色值。下面是删除任何客户端特定值的角色/方法的简化版本,但仍然展示了一个真实的用例。

namespace App.Authentication
{

    /// <summary>
    /// Helper extension methods for checking role membership.  
    /// </summary>
    public static class ClaimsPrincipalExtensions
    {
        /// <summary>
        /// Returns true if user has the System Administrator role.
        /// </summary>
        /// <param name="principal"></param>
        /// <returns>bool</returns>
        public static bool IsSysAdmin(this ClaimsPrincipal principal)
        {
            return principal != null && 
                   (
                       principal.HasClaim(ClaimTypes.GroupSid, SystemGroups.SysAdmin) 
                    || principal.HasClaim(ClaimTypes.Role, SystemRoles.SysAdmin)
                   );
        }
        public static bool IsManager(this ClaimsPrincipal principal)
        {
            return principal != null && 
                   (
                       principal.HasClaim(ClaimTypes.GroupSid, SystemGroups.Manager) 
                    || principal.HasClaim(ClaimTypes.Role, SystemRoles.Manager)
                   );
        }

        public static bool CanManageWorkersAcrossBranches(this ClaimsPrincipal principal)
        {
            return principal != null && principal.IsSysAdmin() || principal.IsManager();
        }
    }
}
namespace App.Authentication
{
    public class SystemGroups
    {
        public const string Manager = "Manager";
        public const string SysAdmin = "SysAdmin";

        // SysAdmin is tacked on to all role combinations as that role is granted access to all parts of the application

        public const string CanManageWorkersAcrossBranches = "Manager, SysAdmin";

    }

    public class SystemRoles
    {
        public const string Manager = @"DOMAIN\Manager";
        public const string SysAdmin = @"DOMAIN\SysAdmin";

        // SysAdmin is tacked on to all role combinations as that role is granted access to all parts of the application

        public const string CanManageWorkersAcrossBranches = @"DOMAIN\Manager, DOMAIN\SysAdmin";

    }
}

在开发模式下运行时,在Controller或视图中使用任一方法时,它们按预期工作。但是,在生产模式下使用它们时,它们总是返回false。

    public async Task<IEnumerable<WorkerProfileListViewModel>> GetWorkerProfile()
    {
        var profiles = this._profileService.AllWorkerProfiles(activeOnly: false);

        // If a user cannot view workers across branches, then filter the data down to their branch only.
        // This returns `false` when it should return `true`
        if (!User.CanManageWorkersAcrossBranches())
        {
            var currentWorker = await this._workerService.GetCurrentWorkerAsync(User);
            profiles = profiles.Where(p => p.BranchCode == currentWorker.BranchCode);
        }

        return profiles.Select(wp => new WorkerProfileListViewModel(wp));
    }

1 个答案:

答案 0 :(得分:0)

找出问题所在。使用principal.HasClaim(ClaimTypes.Role, SystemRoles.SysAdmin)失败是因为声明具有SID作为值,而不是用于配置AD用户组的人类可读名称,这与SystemRoles静态类中使用的值相同

principal.HasClaim(ClaimTypes.Role, SystemRoles.SysAdmin)替换principal.IsInRole(SystemRoles.SysAdmin)适用于使用ClaimsTransformer的dev env以及没有变换器的部署环境和实际用户帐户配置各种用户组/角色。