2011-03-14 51 views
0

是否有任何针对.NET的开源解决方案(更喜欢C#/ MVC),允许在私有滚动Beta方案中使用简单的锁定和邀请系统?网站邀请System/Beta Lockdown for .NET?

差不多在那里,除非他们在(可能使用全球行动过滤器)登录的用户会被重定向到一个醒目网页...

下面是在其他语言中一对夫妇类似的解决方案:

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

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

回答

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类定义中才能使所有工作正常。

+0

@ nathan-taylor甜,看起来像一个很好的开始,谢谢!明天我会提供代码。所以看起来我只是注册'GlobalFilters.Filters.Add(new AccessControlAttribute());'并且可以将defaultPage设置为View? – 2011-03-15 03:24:49

+0

@MarcM重定向基于任意的URL,只要你有一个路由分配给该视图,是的。 – 2011-03-15 06:30:48