2010-03-24 3 views
20

Я бы хотел, чтобы [Authorize] перенаправлял на loginUrl, если я не использую эту роль, например [Authorize (Roles="Admin")]. В этом случае я хочу просто отобразить страницу, в которой пользователь не авторизовался.Как перенаправить [Авторизовать] на loginUrl, только если роли не используются?

Что мне делать?

+0

я задал тот же вопрос здесь: http://stackoverflow.com/questions/2322366/how-do -i-serve-up-an-unauthorized-page-when-a-user-is-not-in-авторизованные роли –

+1

Robert: Спасибо. Я искал похожие сообщения перед публикацией, но не видел ваших. С каким решением вы столкнулись? – royco

+2

Я закончил свой собственный атрибут AuthorizeRoles', используя код из 'AuthorizeAttribute' и изменив его. Если вы можете подождать до завтра, я отправлю код. –

ответ

24

Вот код моей модифицированной реализации AuthorizeAttribute; Я назвал его SecurityAttribute. Единственное, что я изменил это OnAuthorization метода, и я добавил дополнительное строковое свойство для URL-адрес для перенаправления на несанкционированную страницу:

// Set default Unauthorized Page Url here 
private string _notifyUrl = "/Error/Unauthorized"; 

public string NotifyUrl { 
    get { return _notifyUrl; } set { _notifyUrl = value; } 
} 

public override void OnAuthorization(AuthorizationContext filterContext) { 
    if (filterContext == null) { 
     throw new ArgumentNullException("filterContext"); 
    } 

    if (AuthorizeCore(filterContext.HttpContext)) { 
     HttpCachePolicyBase cachePolicy = 
      filterContext.HttpContext.Response.Cache; 
     cachePolicy.SetProxyMaxAge(new TimeSpan(0)); 
     cachePolicy.AddValidationCallback(CacheValidateHandler, null); 
    } 

    /// This code added to support custom Unauthorized pages. 
    else if (filterContext.HttpContext.User.Identity.IsAuthenticated) 
    { 
     if (NotifyUrl != null) 
      filterContext.Result = new RedirectResult(NotifyUrl); 
     else 
      // Redirect to Login page. 
      HandleUnauthorizedRequest(filterContext); 
    } 
    /// End of additional code 
    else 
    { 
     // Redirect to Login page. 
     HandleUnauthorizedRequest(filterContext); 
    } 
} 

Вы называете это точно так же, как оригинал AuthorizeAttribute, за исключением того, что это дополнительное свойство для переопределения Несанкционированное URL страницы:

// Use custom Unauthorized page: 
[Security (Roles="Admin, User", NotifyUrl="/UnauthorizedPage")] 

// Use default Unauthorized page: 
[Security (Roles="Admin, User")] 
+0

Спасибо, это работает хорошо. Вместо того, чтобы изменять AuthorizeAttribute.cs, я просто унаследовал от него. Теперь я могу использовать Роли с [Авторизовать], и мой код будет значительно упрощен. Еще раз спасибо. – royco

+0

Robert: Мне нужно вызвать HandleUnauthorizedRequest (filterContext) из AuthorizeCore, где filterContext недоступен. Я мог бы просто передать filterContext в AuthorizeCore с помощью filterContext.HttpContext. Мысли? – royco

+0

@Bob: AuthorizeCore - это всего лишь локальный метод, поэтому вы должны быть в состоянии делать все, что хотите. –

3

Самый простой способ, который я нашел, - расширить и настроить атрибут AuthorizeAttribute, чтобы он делал что-то другое (то есть не задавал HttpUnauthorizedResult), когда проверка роли не выполняется. Я написал article об этом в своем блоге, который может оказаться полезным. В статье описывается то, что вы хотите, хотя оно идет дальше и позволяет пользователю, который «владеет» данными, также иметь доступ к действию. Я думаю, что это должно быть довольно легко изменить для ваших целей - вам просто нужно удалить часть «или владельца».

+0

Ссылка только ответы недоверчивы, потому что, если ссылка больше не работает, ответ становится бесполезным, пожалуйста, укажите содержание ссылки в ответе здесь. –

+1

Ответ ссылается на мое собственное сообщение в блоге и описывает общий подход - и, следовательно, не является ответом только «ссылка». Я не вижу необходимости копировать весь пост здесь. – tvanfosson

13

Расширьте AuthorizeAttribute класс и переопределить HandleUnauthorizedRequest

public class RoleAuthorizeAttribute : AuthorizeAttribute 
{ 
    private string redirectUrl = ""; 
    public RoleAuthorizeAttribute() : base() 
    { 
    } 

    public RoleAuthorizeAttribute(string redirectUrl) : base() 
    { 
     this.redirectUrl = redirectUrl; 
    } 

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     if (filterContext.HttpContext.Request.IsAuthenticated) 
     { 
      string authUrl = this.redirectUrl; //passed from attribute 

      //if null, get it from config 
      if (String.IsNullOrEmpty(authUrl)) 
       authUrl = System.Web.Configuration.WebConfigurationManager.AppSettings["RolesAuthRedirectUrl"]; 

      if (!String.IsNullOrEmpty(authUrl)) 
       filterContext.HttpContext.Response.Redirect(authUrl); 
     } 

     //else do normal process 
     base.HandleUnauthorizedRequest(filterContext); 
    } 
} 

Использование

[RoleAuthorize(Roles = "Admin, Editor")] 
public class AccountController : Controller 
{ 

} 

И убедитесь, что вы добавить запись AppSettings в конфигурации

<appSettings> 
    <add key="RolesAuthRedirectUrl" value="http://mysite/myauthorizedpage" /> 
</appSettings> 
Смежные вопросы