17

ASP.Net MVC4Webアプリケーションを開発しています。以前、私の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;

}

このコードは以前のMVC3アプリケーションではうまく機能しますが、このMVC 4アプリケーションでは、Razorビュー内で、次のコードがIsInRoleプロパティにアクセスして役割チェックを実行していないようです。

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

繰り返しますが、これは私のMVC3アプリケーションで完全に機能しました。

これが私のMVC4アプリケーションで機能しない理由について誰かがアイデアや提案を持っていますか?

どんな助けでも大歓迎です。

ありがとう。

追加情報

私のMVC4アプリケーションは.NetFramework4.0を使用しています

以下のスクリーンショットは、 Context.Userに割り当てられている私のジェネリックプリンシパルを示しています。このユーザーの場合、m_rolesにはUserID(100170)とそのRole (Applicant)の2つの文字列が含まれていることがわかります。しかし、何らかの理由で、IsInRolesにアクセスしたりMVC 4 Razor Viewで表示したりすることはできませんが、同じMVC 3RazorViewで表示することはできます。 ここに画像の説明を入力してください

4

3 に答える 3

19

人々

私はついにこの問題を解決しました。新しいASP.NETMVC4アプリケーションを作成すると、デフォルトでSimpleMembershipProviderが有効になっているように見えます。この機会にSimpleMembershipProviderを使用したくありませんでしたが、次の行を使用してWeb構成でSimpleMembershipProviderを無効にする必要がありました。

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

User.IsInRoleへの私の呼び出しは今うまくいきます。

これが他の誰かに役立つことを願っています。

于 2013-02-11T11:16:10.200 に答える
4

MVC 4では、Userからにアクセスできるため、razor構文内でインスタンス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)
于 2013-02-10T12:55:16.077 に答える
1

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; }
        }
    }

次に、Viewsフォルダーのweb.configのsystem.web.webPages.razor/pagesセクションに次の変更を加えます。

<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>

これで問題が解決することを願っています。

于 2013-02-10T20:23:06.413 に答える