Как подключиться к автоматическому повторному входу? - PullRequest
1 голос
/ 25 августа 2011

Я делаю приложение ASP.Net MVC3.Сейчас я использую встроенный код аутентификации, который поставляется с проектом Visual Studio 2010.Проблема в том, что мне нужно получить идентификатор базы данных вошедшего в систему пользователя, как только он вошел в систему. Теперь я делаю это, добавляя код к действию входа в систему контроллера учетных записей, который получает идентификатор из базы данных, просматривая его по имени пользователя.,Это работает для новых логинов, но не для «запоминающихся».При перезапуске приложения последний пользователь автоматически снова входит в систему, но код входа не запускается, поэтому я не получаю идентификатор базы данных.

Как мне решить эту проблему?

РЕДАКТИРОВАТЬ:Я попытался реализовать решения Дэниела, которые выглядят многообещающе, и я придумал этот код.Это никогда не называют, хотя!Где я ошибся?

Global.asax.cs:

protected void Application_Start()
{
    Database.SetInitializer<StandInContext>(new StandInInitializer());

    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    this.AuthenticateRequest +=
       new EventHandler(MvcApplication_AuthenticateRequest);
}

void MvcApplication_AuthenticateRequest(object sender, EventArgs e)
{
    if(Request.IsAuthenticated)
    {
        using (var db = new StandInContext())
        {
            var authenticatedUser = db.AuthenticatedUsers.SingleOrDefault(
                user => user.Username == User.Identity.Name);
            if (authenticatedUser == null)
                return;
            var person = db.Persons.Find(authenticatedUser.PersonID);
            if (person == null)
                return;

            Context.User = new CustomPrincipal(
                             User.Identity, new string[] { "user" })
                           {
                               Fullname = person.FullName,
                               PersonID = person.PersonID,
                           };
        }
    }
}

Ответы [ 2 ]

3 голосов
/ 25 августа 2011

Вы можете использовать событие AuthenticateRequest в вашем Global.asax.cs:

protected void Application_AuthenticateRequest()
{
    if (Request.IsAuthenticated)
    {
        // retrieve user from repository
        var user = _membershipService.GetUserByName(User.Identity.Name);
        // do other stuff
    }
}

Обновление:

Теперь, когдаЯ вижу, что вы пытаетесь сделать немного яснее, я бы рекомендовал не использовать сессии в этом конкретном случае.Одна из причин заключается в том, что Session требует ссылку на System.Web, к которой у вас нет доступа из некоторых мест, например, к уровню бизнес-логики в отдельной библиотеке классов.IPrincipal, с другой стороны, существует именно по этой причине.

Если вам нужно хранить больше информации о пользователях, чем предоставляет IPrincioal, вы просто реализуете ее и добавляете свои собственные свойства вЭто.Еще проще, вы можете просто извлечь из GenericPrincipal, который реализует IPrincipal и добавляет некоторые основные функции проверки роли:

CustomPrincipal.cs

public class CustomPrincipal : GenericPrincipal
{
    public CustomPrincipal(IIdentity identity, string[] roles)
        : base(identity, roles) { }

    public Guid Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email  { get; set; }
    ...
}

Итак, вызамените участника по умолчанию своим собственным в AuthenticateRequest, как и раньше:

Global.asax.cs

protected void Application_AuthenticateRequest()
{
    if (Request.IsAuthenticated)
        Context.User = _securityService.GetCustomPrincipal(User.Identity.Name);
}

И это все.Самое большое преимущество, которое вы получаете, - это то, что вы автоматически получаете доступ к своим пользовательским данным буквально повсюду, без необходимости вставлять параметр userId во все ваши методы.Все, что вам нужно сделать, это вернуть текущий принципал обратно в CustomPrincipal и получить доступ к вашим данным следующим образом:

Из ваших бритвенных представлений:

<p>Hello, @((CustomPrincipal)User).FirstName!</p>

С ваших контроллеров:

var firstName = ((CustomPrincipal)User).FirstName;

Из уровня бизнес-логики в другой сборке:

var firstName = ((CustomPrincipal)Thread.CurrentPrincipal).FirstName;

Для сохранения СУХОГО, вы можете упаковать его в метод расширения и повесить его на IPrincipal, например:

public static class PrincipalExtensions
{
    public static string GetFirstName(this IPrincipal principal)
    {
        var customPrincipal = principal as CustomPrincipal;
        return customPrincipal != null ? customPrincipal.FirstName : "";
    }
}

И тогда вы просто сделаете @User.GetFirstName(), var userName = User.GetFirstName(), Thread.CurrentPrincipal.GetFirstName() и т. Д.

Надеюсь, это поможет.

1 голос
/ 25 августа 2011

Я не думал ясно. Я пытался сохранить информацию о пользователе в объекте Session, пока она доступна через объект User. Извините, что потратил впустую ваше время.

...