Подтвердить что ты не робот

ASP.Net MVC 4 Общие принципиальные трудности

Я разрабатываю веб-приложение ASP.Net MVC 4. Ранее мои приложения MVC были разработаны с использованием MVC 3 и с этим новым приложением MVC 4. Я только что скопировал/повторно использовал мой код аутентификации и авторизации. предыдущих приложений.

Когда пользователь регистрируется на моем сайте, я делаю следующее

Контроллер учетных записей

public ActionResult Login(LoginModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        User user = _userService.GetUser(model.Email.Trim());

        //Create Pipe Delimited string to store UserID and Role(s)
        var userData = user.ApplicantID.ToString();

        foreach (var role in user.UserRoles)
        {
            userData = userData + "|" + role.description;
        }

        _formAuthService.SignIn(user.ApplicantFName, false, userData);

        return RedirectToAction("Index", "Portfolio");
        }

        return View(model);
    }

FormsAuthenticationService

public class FormsAuthenticationService : IFormsAuthenticationService
{
    public void SignIn(string userName, bool createPersistentCookie, string UserData)
    {
        if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");

        // Create and tuck away the cookie
        FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddDays(15), createPersistentCookie, UserData);
        // Encrypt the ticket.
        string encTicket = FormsAuthentication.Encrypt(authTicket);

        //// Create the cookie.
        HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
        HttpContext.Current.Response.Cookies.Add(faCookie);
    }
}

Global.asax

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{

    // Get the authentication cookie
    string cookieName = FormsAuthentication.FormsCookieName;
    HttpCookie authCookie = Context.Request.Cookies[cookieName];

    // If the cookie can't be found, don't issue the ticket
    if (authCookie == null) return;

    // Get the authentication ticket and rebuild the principal
    // & identity
    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

    string[] UserData = authTicket.UserData.Split(new Char[] { '|' });

    GenericIdentity userIdentity = new GenericIdentity(authTicket.Name);
    GenericPrincipal userPrincipal = new GenericPrincipal(userIdentity, UserData);
    Context.User = userPrincipal;

}

Этот код хорошо работает в моих предыдущих приложениях MVC 3, но в этом приложении MVC 4 внутри Razor View следующий код, похоже, не имеет доступа к свойству IsInRole для выполнения проверки роли

@if (HttpContext.Current.User.IsInRole("Applicant"))
{
    <p>text</text>
}

Опять же, это отлично работало в моих приложениях MVC 3.

Есть ли у кого-нибудь идеи или предложения относительно того, почему это не будет работать с моим приложением MVC 4?

Любая помощь очень ценится.

Спасибо.

Дополнительные сведения

В моем приложении MVC 4 используется .Net Framework 4.0

На скриншоте ниже показан мой Generic Principal, которому назначено Context.User. Вы можете видеть, что для этого пользователя m_roles содержит две строки: Пользовательский (100170) и их Роль (Заявитель). Но по какой-либо причине, IsInRoles недоступен или не отображается в моем MVC 4 Razor View, однако это может быть в моей идентичной MVC 3 Razor Посмотреть. enter image description here

4b9b3361

Ответ 1

Люди

Я, наконец, решил эту проблему. Он появляется по умолчанию, когда SimpleMembershipProvider включен, когда вы создаете новое приложение ASP.NET MVC 4. Я не хотел использовать SimpleMembershipProvider в этом случае, однако мне нужно было отключить его в моей веб-конфигурации со следующей строкой

<appSettings>
    <add key="enableSimpleMembership" value="false" />
</appSettings>

Мой вызов User.IsInRole отлично работает сейчас.

Надеюсь, это поможет кому-то еще.

Ответ 2

В MVC 4 вы можете получить доступ к User из WebPageRenderingBase, поэтому внутри синтаксиса бритвы у вас есть прямой доступ к экземпляру User:

@if (Request.IsAuthenticated && User.IsInRole("Applicant"))
{
    <p>text</p>
}

Я вижу, что вы создаете FormsAuthenticationTicket и HttpCookie вручную. Класс FormsAuthentication сделает это для вас, используя SetAuthCookie(string, bool[, string]). В этом смысле ваша служба авторизации может быть уменьшена до:

public class FormsAuthenticationService : IFormsAuthenticationService
{
    public void SignIn(string userName, bool createPersistentCookie, string UserData)
    {
        if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");

        FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
    }
}

Оказывается, вам также нужно изменить Application_AuthenticateRequest на Application_OnPostAuthenticateRequest:

protected void Application_OnPostAuthenticateRequest(Object sender, EventArgs e)

Ответ 3

В MVC 4 HttpContext.Current.User не отображается, поэтому вы не можете его использовать. То, что я сделал, это создать пользовательский BaseViewPage и добавить в него следующий код.

    public abstract class BaseViewPage : WebViewPage
    {
        public virtual new Principal User
        {
            get { return base.User as Principal; }
        }
    }

    public abstract class BaseViewPage<TModel> : WebViewPage<TModel>
    {
        public virtual new Principal User
        {
            get { return base.User as Principal; }
        }
    }

И затем сделайте следующие изменения в разделе system.web.webPages.razor/pages вашего web.config в папке Просмотры.

<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="WebApp.Views.BaseViewPage">
  <namespaces>
    ...
  </namespaces>
</pages>

Надеюсь, что это решает вашу проблему.