Я написал небольшой фильтр контроля доступа для 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>
При указанной выше конфигурации любой пользователь, который не вошел в систему или не является участником роли «Участники», будет перенаправлен на «~ / пригласить только.HTM.Вы можете указать несколько разрешенных ролей и / или пользователей, разделяя запятые в атрибутах 'allowRoles' и 'allowUsers'.
AccessControlAttribute
должен быть зарегистрирован как глобальный фильтр или, в качестве альтернативы, размещен в BaseController.определение класса, чтобы все заработало.