Доступ к пользовательскому принципалу в пользовательском ActionFilterAttribute - PullRequest
2 голосов
/ 06 августа 2010

Я работаю над приложением ASP.NET MVC. Я реализовал пользовательское членство провайдера, принципала и личность. В пользовательском поставщике я заменяю HttpContext.Current.User в методе ValidateUser () следующим образом:

public sealed class CustomMembershipProvider : MembershipProvider {  
    ...  
    public override bool ValidateUser(string username, string password) {  
      ...  
      CustomIdentity identity = new CustomIdentity(...);  
      CustomPrincipal cu = new CustomPrincipal(identity);  
      HttpContext.Current.User = cu;  
      ...  
    }  
    ...  
}

В AccountController (вызывает провайдера пользовательского членства) я могу получить доступ к пользовательскому идентификатору следующим образом:

public class AccountController : BaseController {  
  ...  
  public ActionResult LogOn(string userName,   
                            string password,   
                            bool rememberMe,   
                            string returnUrl) {  
    ...  
    CustomIdentity ci = (CustomIdentity)HttpContext.User.Identity;  
    ...  
  }  
  ...  
}

Все мои контроллеры наследуют BaseController, который вызывает пользовательский атрибут следующим образом:

[CustomAttribute]  
public abstract class BaseController : Controller {  
  ...  
}  

Я хочу, чтобы другие мои контроллеры имели доступ к пользовательской идентификации в пользовательском атрибуте после того, как он был установлен AccountController, следующим образом:

public class CustomAttribute : ActionFilterAttribute {  
  public override void OnActionExecuting(ActionExecutingContext filterContext) {  
    base.OnActionExecuting(filterContext);  
    CustomIdentity ci = filterContext.HttpContext.User.Identity as CustomIdentity;  
    ...  
    }  
  }  
}  

Я обнаружил, что filterContext.HttpContext.User по-прежнему имеет значение GenericPrincipal, а не мой CustomPrincipal. Так что моя личность не доступна в моём фильтре атрибутов. Что мне нужно сделать, чтобы мой CustomPrincipal был доступен в моем фильтре атрибутов?

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 07 августа 2010

После более подробного изучения того, как инициируются события запроса приложения (конкретный порядок) и когда можно устанавливать объекты контекста, я смог установить свой собственный принципал и идентификатор, чтобы они были доступны для фильтра (в данном случае в приложении). ).

Я понял, что пользователь должен пройти проверку подлинности, прежде чем эти объекты можно будет настроить для использования в остальной части приложения. Я обнаружил, что это можно сделать с помощью метода Application_AuthenticateRequest () файла global.asax.

Итак, я изменил свою логику следующим образом:

  1. Удалено создание настраиваемого участника и удостоверения из метода ValidateUser () настраиваемого поставщика.
  2. Вместо этого ValidateUser () после проверки имени пользователя и пароля по отношению к пользовательскому хранилищу кэширует всю необходимую мне информацию в HttpContext.Current.Cache, используя имя пользователя в качестве уникального ключа.
  3. Наконец, я добавил следующую логику в Application_AuthenticateRequest (), чтобы установить мой пользовательский принципал и идентификатор, извлекая общие свойства идентификатора и расширяя его пользовательскими свойствами, которые я сохранял в кэше. Я проиндексировал кеш, используя имя, хранящееся в общей идентификации, так как именно этот ключ я использовал для создания кеша.
protected void Application_AuthenticateRequest(object sender, EventArgs e) {  

  if (Request.IsAuthenticated) {  

    // TODO: Add checks so we only do the following once per login.

    // Get the GenericPrincipal identity  
    IIdentity ui = HttpContext.Current.User.Identity;  

    /* Extract Name, isAuthenticated, AuthenticationType from
       the identity of the GenericPrincipal and add them including 
       any custom properties to the custom identity. I added a 
       few extra properties to my custom identity. */

    CustomIdentity identity = new CustomIdentity(...);

    /* Although my custom principal does not currently 
       have any additional properties, I created a new  
       principal as I plan to add them in the future. */

    CustomPrincipal principal = new CustomPrincipal(identity);

    // Set custom principal 
    HttpContext.Current.User = principal;

  }
}

Это преодолело мои препятствия. Пожалуйста, помогите мне, если есть другие лучшие способы сделать то же самое.

Спасибо.

0 голосов
/ 07 августа 2010

Я не знаю, является ли это "лучшим" способом, но пока он работал для меня. Я создаю статический UserContext класс, который имеет свойство CurrentUser. Там я сохраняю сущность пользователя, которую я получаю из базы данных, и использую ее для получения информации о пользователе и авторизации. Я использую только HttpContext.Current.User для проверки подлинности.

Теперь свойство CurrentUser хранит мой пользовательский объект в коллекции HttpContext Items (у меня есть обертка вокруг этого, чтобы я мог сделать его тестируемым на модуле).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...