.NET C/S架构软件用户授权设计方案(mac地址+白名单用户)|C/S开发框架
作者:csframework|C/S框架网  发布日期:2024/11/29 14:53:12

.NET C/S架构软件用户授权设计方案(mac地址+白名单用户)|C/S开发框架

.NET C/S架构软件用户授权设计方案(mac地址+白名单用户)

设计目的

我们发布软件产品后要能限制用户使用权限,如:软件过期,发布试用版软件给用户使用。

案例开发环境

  • VS2022+C#
  • SqlServer 2012

设计方案

设计白名单表 - sys_ClientWhitelist

C# 全选
CREATE TABLE [dbo].[sys_ClientWhitelist]
(
	[isid] [varchar](50) NOT NULL,
	[MAC] [varchar](50) NULL,
	[ExpireTime] [datetime] NULL,
	[FlagUse] [varchar](1) NULL,
	[Remark] [varchar](200) NULL,
	[CreationTime] [datetime] NULL,
	[CreatedBy] [varchar](50) NULL
)

字段说明

  • isid:记录主键
  • MAC:mac地址
  • ExpireTime:软件过期时间
  • FlagUse:是否启用,Y:启用,N:不启用
  • Remark:备注
  • CreationTime:记录创建时间
  • CreatedBy:创建人

软件授权接口设计 - IUserLicenseProvider

为了扩展其他授权策略,我们使用接口解耦。

C# 全选
    /// <summary>
    /// 软件授权接口
    /// </summary>
    public interface IUserLicenseProvider
    {
        /// <summary>
        /// 检查软件授权,没有授权则抛出异常
        /// </summary>
        void Check();

        /// <summary>
        /// 软件是否过期,True:过期,False:没过期
        /// </summary>
        /// <returns></returns>
        bool IsExpired();

        /// <summary>
        /// 软件授权信息,校验结果信息
        /// </summary>
        UserLicenseInfo LicenseInfo { get; }

    }

用户授权校验结果类 - UserLicenseInfo

C# 全选
    /// <summary>
    /// 用户授权校验结果
    /// </summary>
    public class UserLicenseInfo
    {
        /// <summary>
        /// 校验的Mac地址
        /// </summary>
        public string ValidMacAddress { get; set; }

        /// <summary>
        /// 软件过期日期
        /// </summary>
        public DateTime ExpireTime { get; set; }

        /// <summary>
        /// 软件是否过期
        /// </summary>
        public bool IsExpired { get; set; }

        /// <summary>
        /// 软件剩余天数
        /// </summary>
        public double DaysRemaining { get; set; }

        /// <summary>
        /// 校验结果信息
        /// </summary>
        public string ValidateResult { get; set; }
    }

实现策略:mac地址+白名单用户 - MacBlacklistProvider

类定义为 internal(仅dll内部使用)

C# 全选
    /// <summary>
    /// Mac地址+白名单用户,授权策略
    /// </summary>
    internal class MacBlacklistProvider : IUserLicenseProvider
    {
        //授权的用户列表
        internal static List<sys_ClientWhiteList> _Cache = null;

        private UserLicenseInfo _LicenseInfo = null;

        public UserLicenseInfo LicenseInfo
        {
            get { return _LicenseInfo; }
        }

        /// <summary>
        /// 检查用户授权是否过期
        /// </summary>
        /// <exception cref="BizException"></exception>
        public void Check()
        {
            if (IsExpired())
            {
                throw new BizException(_LicenseInfo.ValidateResult);
            }
        }

        /// <summary>
        /// 检查用户授权是否过期。
        /// </summary>
        /// <returns>true:软件已过期,false:没有过期</returns>
        /// <exception cref="BizException"></exception>
        public bool IsExpired()
        {
            this.LoadCache(true);

            _LicenseInfo = new UserLicenseInfo
            {
                IsExpired = false,
                ValidateResult = "软件使用正常,感谢您的支持!",
            };

            //获取电脑的mac地址
            var mac = NetTools.GetMacByNetworkInterface().Where(w => !string.IsNullOrEmpty(w))
                .Select(s => s.ToUpper()).Distinct().ToList();

            sys_ClientWhiteList row = null;

            //一台电脑有多个mac地址
            if (mac != null && mac.Count > 0)
            {
                row = _Cache.Where(w => mac.Contains(w.MAC) && w.FlagUse == "Y").FirstOrDefault();

                if (row == null)
                {
                    _LicenseInfo.IsExpired = true;
                    _LicenseInfo.ValidateResult = "您没有授权使用本软件,请联系供应商!";
                }
                else
                {
                    _LicenseInfo.IsExpired = row.ServerTime > row.ExpireTime;//判断软件过期:服务器日期>软件过期日期
                    _LicenseInfo.DaysRemaining = (row.ExpireTime.Value - row.ServerTime.Value).TotalDays;
                    _LicenseInfo.ExpireTime = row.ExpireTime.Value;
                    _LicenseInfo.ValidMacAddress = row.MAC;

                    if (_LicenseInfo.IsExpired)
                    {
                        _LicenseInfo.ValidateResult = "软件已过期,请联系供应商!";
                    }
                }
            }

            return _LicenseInfo.IsExpired;
        }

        /// <summary>
        /// 加载授权数据(mac+白名单)
        /// </summary>
        /// <param name="refreshData">是否刷新缓存数据</param>
        private void LoadCache(bool refreshData = true)
        {
            if (refreshData || _Cache == null || _Cache.Count == 0)
            {
                _Cache = new bllUser().GetClientWhitelist();

                //84-97-F6-89-E8-A0 => 去掉横杆
                _Cache.ForEach(i => i.MAC = i.MAC.Replace("-", "").Trim().ToUpper());
            }
        }

    }

DAL层,获取软件用户白名单列表

C# 全选
        /// <summary>
        /// DAL层获取软件用户白名单列表
        /// </summary>
        /// <returns></returns>
        public List<sys_ClientWhiteList> GetClientWhitelist()
        {
            //仅获取启用的记录(FlagUse == "Y")
            var list = _Database.GetQueryable<sys_ClientWhiteList>().Where(w => w.FlagUse == "Y").ToList();
            var time = _Database.GetServerTime();
            list.ForEach(i => i.ServerTime = time);
            return list;
        }

获取本地mac地址

参考:C#网络工具类NetTools,获取IP/MAC地址

https://www.cscode.net/archive/newdoc/254824675938309.html

用户软件授权提供者 - UserLicenseProvider

C# 全选
    /// <summary>
    /// 用户软件授权提供者
    /// </summary>
    public static class UserLicenseProvider
    {
        static IUserLicenseProvider _Stratage = null;

        /// <summary>
        /// 用户授权校验策略,单例模式
        /// </summary>
        public static IUserLicenseProvider Current
        {
            get
            {
                if (_Stratage == null) _Stratage = new MacBlacklistProvider();

                return _Stratage;
            }
        }
    }

使用方法

CSFrameworkV6旗舰版开发框架

C# 全选
    if (BridgeFactory.InitializeBridge())//初始化后台数据连接
    {
        //检查软件授权
        UserLicenseProvider.Current.Check();

        //省略其他代码
    }

其他软件

C# 全选
    //初始化后台数据连接
    //省略代码............

    //检查软件授权
    UserLicenseProvider.Current.Check();

测试报告

Test Case1

测试电脑的mac地址:00-E0-4C-44-17-F4

.NET C/S架构软件用户授权设计方案(mac地址+白名单用户)|C/S开发框架

测试结果:没有软件登记、软件授权

.NET C/S架构软件用户授权设计方案(mac地址+白名单用户)|C/S开发框架

Test Case2

测试电脑的mac地址:00-E0-4C-44-17-F4

启用:FlagUse=Y

过期时间:2024-11-24(当前时间:2024-11-25)

.NET C/S架构软件用户授权设计方案(mac地址+白名单用户)|C/S开发框架

测试结果:软件已过期

.NET C/S架构软件用户授权设计方案(mac地址+白名单用户)|C/S开发框架

Test Case3

测试电脑的mac地址:00-E0-4C-44-17-F4

过期时间:2024-11-26(当前时间:2024-11-25)

不启用:FlagUse=N

.NET C/S架构软件用户授权设计方案(mac地址+白名单用户)|C/S开发框架

测试结果:您没有授权使用本软件,请联系供应商!

.NET C/S架构软件用户授权设计方案(mac地址+白名单用户)|C/S开发框架

Test Case4

测试电脑的mac地址:00-E0-4C-44-17-F4

过期时间:2024-11-29(当前时间:2024-11-25)

不启用:FlagUse=Y

测试结果:软件运行正常,剩余使用天数:3

.NET C/S架构软件用户授权设计方案(mac地址+白名单用户)|C/S开发框架

C/S框架网|原创精神.创造价值.打造精品


扫一扫加作者微信
C/S框架网作者微信 C/S框架网|原创作品.质量保障.竭诚为您服务
上一篇 下一篇