2011-03-14 3 views
0

개인 롤링 베타 시나리오에서 유용한 간단한 잠금 및 초대 시스템을 허용하는 .NET 용 오픈 소스 솔루션 (C#/MVC 선호)이 있습니까?웹 사이트 .NET 용 System/Beta Lockdown을 초대 하시겠습니까?

들이 (아마도 글로벌 액션 필터를 사용하여)에 로그인하지 않는 사용자가 시작 페이지로 리디렉션 될 경우 꽤 많이 ... 여기

다른 언어에서 몇 유사한 솔루션은 다음과 같습니다

https://github.com/ejdraper/exclusivity (루비)

https://github.com/pragmaticbadger/django-privatebeta (파이썬)

답변

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로 설정할 수 있습니까? –

+0

@MarcM 리디렉션은 임의의 URL을 기반으로하므로 해당보기에 라우트가 할당 된 경우에만 가능합니다. –

관련 문제