【问题标题】:Website Invite System / Beta Lockdown for .NET?.NET 的网站邀请系统/Beta 锁定?
【发布时间】:2011-07-15 10:21:23
【问题描述】:

是否有任何 .NET 的开源解决方案(首选 C#/MVC)允许简单的锁定和邀请系统在私人滚动 Beta 场景中有用?

除非用户登录(可能使用全局操作过滤器),否则用户几乎会被重定向到启动页面...

以下是其他语言的几个类似解决方案:

https://github.com/ejdraper/exclusivity(红宝石)

https://github.com/pragmaticbadger/django-privatebeta (Python)

【问题讨论】:

    标签: c# .net asp.net-mvc-3 beta


    【解决方案1】:

    我为配置文件驱动的 ASP.NET MVC 编写了一个小的“访问控制”过滤器。我可以在 web.config 中切换一个标志,它将所有未注册的用户移动到特定页面,除非他们特别请求登录或注销操作。您可以相应地调整您的实现,而不会有太多麻烦。

    过滤属性

    public class AccessControlAttribute : AuthorizeAttribute
    {
        public bool AccessControlEnabled {
            get { return AccessControlSection.Settings != null; }
        }
    
        public bool LockoutEnabled {
            get { return AccessControlEnabled && AccessControlSection.Settings.ForceLockout != null && AccessControlSection.Settings.ForceLockout.Enabled; }
        }
    
        public AccessControlAttribute() {
            if (LockoutEnabled) {
                Roles = AccessControlSection.Settings.ForceLockout.AllowRoles;
                Users = AccessControlSection.Settings.ForceLockout.AllowUsers;
            }
        }
    
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
            if (filterContext.IsChildAction || ApproveLockoutAction(filterContext))
                return;
    
            if (LockoutEnabled && !string.IsNullOrEmpty(AccessControlSection.Settings.ForceLockout.DefaultPage)) {
                filterContext.HttpContext.Response.Redirect(AccessControlSection.Settings.ForceLockout.DefaultPage, false);
                return;
            }
    
            base.HandleUnauthorizedRequest(filterContext);
        }
    
        private static bool ApproveLockoutAction(AuthorizationContext filterContext) {
            var forceLockout = AccessControlSection.Settings.ForceLockout;
            if (forceLockout == null || !forceLockout.Enabled)
                return true;
    
            if (string.IsNullOrEmpty(forceLockout.LogOnUrl) || string.IsNullOrEmpty(forceLockout.LogOffUrl))
                return false;
    
            if (filterContext.HttpContext.Request.AppRelativeCurrentExecutionFilePath.Equals(forceLockout.LogOnUrl, StringComparison.OrdinalIgnoreCase)
                || filterContext.HttpContext.Request.AppRelativeCurrentExecutionFilePath.Equals(forceLockout.LogOffUrl, StringComparison.OrdinalIgnoreCase)) {
                return true;
            }
    
            return false;
        }
    }
    

    配置处理程序

    public class AccessControlSection : ConfigurationSection
    {
        public const string SectionName = "accessControl";
        public const string ForceLockoutKeyName = "forceLockout";
    
        private static AccessControlSection _settings;
        public static AccessControlSection Settings {
            get {
                if (_settings == null) {
                    object section = ConfigurationManager.GetSection(SectionName);
                    if (section != null)
                        _settings = section as AccessControlSection;
                }
                return _settings;
            }
        }
    
        [ConfigurationProperty(ForceLockoutKeyName)]
        public ForceLockoutElement ForceLockout {
            get { return (ForceLockoutElement)this[ForceLockoutKeyName]; }
            set { this[ForceLockoutKeyName] = value; }
        }
    }
    
    public class ForceLockoutElement : ConfigurationElement
    {
        public const string AllowRolesKeyName = "allowRoles";
        public const string AllowUsersKeyName = "allowUsers";
        public const string DefaultPageKeyName = "defaultPage";
        public const string EnabledKeyName = "enabled";
        public const string LogOnUrlKeyName = "logOnUrl";
        public const string LogOffUrlKeyName = "logOffUrl";
    
        [ConfigurationProperty(AllowRolesKeyName, DefaultValue = "Admin")]
        public string AllowRoles {
            get { return (string)this[AllowRolesKeyName]; }
            set { this[AllowRolesKeyName] = value; }
        }
    
        [ConfigurationProperty(AllowUsersKeyName)]
        public string AllowUsers {
            get { return (string)this[AllowUsersKeyName]; }
            set { this[AllowUsersKeyName] = value; }
        }
    
        [ConfigurationProperty(DefaultPageKeyName, DefaultValue = "~/offline.htm")]
        public string DefaultPage {
            get { return (string)this[DefaultPageKeyName]; }
            set { this[DefaultPageKeyName] = value; }
        }
    
        [ConfigurationProperty(LogOnUrlKeyName, DefaultValue = "~/auth/logon")]
        public string LogOnUrl {
            get { return (string)this[LogOnUrlKeyName]; }
            set { this[LogOnUrlKeyName] = value; }
        }
    
        [ConfigurationProperty(LogOffUrlKeyName, DefaultValue = "~/auth/logoff")]
        public string LogOffUrl {
            get { return (string)this[LogOffUrlKeyName]; }
            set { this[LogOffUrlKeyName] = value; }
        }
    
        [ConfigurationProperty(EnabledKeyName, DefaultValue = true)]
        public bool Enabled {
            get { return (bool)this[EnabledKeyName]; }
            set { this[EnabledKeyName] = value; }
        }
    
        public string[] AllowedUsersArray {
            get {
                if (string.IsNullOrEmpty(AllowUsers))
                    return null;
    
                return AllowUsers.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);
            }
        }
    
        public string[] AllowRolesArray {
            get {
                if (string.IsNullOrEmpty(AllowRoles))
                    return null;
    
                return AllowRoles.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            }
        }
    }
    

    Web.config 示例

    <configuration>
        <configSections>
            <section name="accessControl" type="MyWebsite.Config.AccessControlSection, MyWebsite" />
        </configSections>
    
        <accessControl>
            <forceLockout enabled="true" defaultPage="~/inviteonly.htm" 
                logOnUrl="~/logon" 
                logOffUrl="~/logoff" 
                allowRoles="Members" />
        </accessControl>
    
    </configuration>
    

    使用上述配置,任何未登录或不是角色“成员”成员的用户都将被重定向到“~/inviteonly.htm”。您可以通过逗号分隔“allowRoles”和“allowUsers”属性中的值来指定多个允许的角色和/或用户。

    AccessControlAttribute 必须注册为全局过滤器,或者放置在 BaseController 类定义中以使一切正常。

    【讨论】:

    • @nathan-taylor 看起来不错的开始,谢谢!明天我会给代码一个去。所以看起来我只是注册GlobalFilters.Filters.Add(new AccessControlAttribute()); 并且可以将 defaultPage 设置为 View 吗?
    • @MarcM 重定向基于任意 URL,因此只要您有分配给该视图的路由,是的。
    猜你喜欢
    • 2012-09-12
    • 2010-12-29
    • 2018-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多