質問

ASP.NET MVCを使用して、2つの非常に異なるタイプのユーザーを持つWebアプリケーションを構築しています。例を考えて、あるタイプはコンテンツプロデューサー(パブリッシャー)で、別のタイプはコンテンツコンシューマー(サブスクライバー)であると言います。

組み込みのASP.NET承認機能を使用する予定はありません。ユーザータイプの分離は二分法であり、あなたはパブリッシャーかサブスクライバーのどちらかであり、両方ではないからです。そのため、組み込みの承認は必要以上に複雑です。さらに、MySQLの使用を計画しています。

列挙フィールド(技術的にはintフィールド)を持つ同じテーブルに保存することを考えていました。次に、そのページに必要なuserTypeを渡すCustomAuthorizationAttributeを作成します。

たとえば、PublishContentページにはuserType == UserType.Publisherが必要であるため、パブリッシャーのみがアクセスできます。そのため、この属性を作成すると、HttpContextBaseにアクセスできるようになります。HttpContextBaseには、標準のユーザーフィールド(IPrincipal型)が含まれます。このIPrincipalにUserTypeフィールドを取得するにはどうすればよいですか?したがって、私の属性は次のようになります。

public class PublisherAuthorizationAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (!httpContext.User.Identity.IsAuthenticated)
            return false;

        if (!httpContext.User.Identity.UserType == UserTypes.Publisher)
            return false;

        return true;
    }
}

または、私のアプローチ全体に欠陥があると思う人はいますか?

役に立ちましたか?

解決

組み込みのASP.NETフォーム認証を引き続き使用しますが、ニーズに合わせてカスタマイズします。

したがって、Userクラスを取得してIPrincipalインターフェイスを実装し、独自のカスタムCookie処理を記述する必要があります。次に、組み込みの[Authorize]属性を使用するだけです。

現在、次のようなものがあります...

global.asaxで

protected void Application_AuthenticateRequest()
{
    HttpCookie cookie = Request.Cookies.Get(FormsAuthentication.FormsCookieName);
    if (cookie == null)
        return;

    bool isPersistent;
    int webuserid = GetUserId(cookie, out isPersistent);

    //Lets see if the user exists
    var webUserRepository = Kernel.Get<IWebUserRepository>();

    try
    {
        WebUser current = webUserRepository.GetById(webuserid);

        //Refresh the cookie
        var formsAuth = Kernel.Get<IFormsAuthService>();

        Response.Cookies.Add(formsAuth.GetAuthCookie(current, isPersistent));
        Context.User = current;
    }
    catch (Exception ex)
    {
        //TODO: Logging
        RemoveAuthCookieAndRedirectToDefaultPage();
    }
}

private int GetUserId(HttpCookie cookie, out bool isPersistent)
{
    try
    {
        FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
        isPersistent = ticket.IsPersistent;
        return int.Parse(ticket.UserData);
    }
    catch (Exception ex)
    {
        //TODO: Logging

        RemoveAuthCookieAndRedirectToDefaultPage();
        isPersistent = false;
        return -1;
    }
}

AccountController.cs

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult LogOn(LogOnForm logOnForm)
{
    try
    {
        if (ModelState.IsValid)
        {
            WebUser user = AccountService.GetWebUserFromLogOnForm(logOnForm);

            Response.Cookies.Add(FormsAuth.GetAuthCookie(user, logOnForm.RememberMe));

            return Redirect(logOnForm.ReturnUrl);
        }
    }
    catch (ServiceLayerException ex)
    {
        ex.BindToModelState(ModelState);
    }
    catch
    {
        ModelState.AddModelError("*", "There was server error trying to log on, try again. If your problem persists, please contact us.");
    }

    return View("LogOn", logOnForm);
}

そして最後に私のFormsAuthService:

public HttpCookie GetAuthCookie(WebUser webUser, bool createPersistentCookie)
{
    var ticket = new FormsAuthenticationTicket(1,
                                               webUser.Email,
                                               DateTime.Now,
                                               DateTime.Now.AddMonths(1),
                                               createPersistentCookie,
                                               webUser.Id.ToString());

    string cookieValue = FormsAuthentication.Encrypt(ticket);

    var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookieValue)
                         {
                             Path = "/"
                         };

    if (createPersistentCookie)
        authCookie.Expires = ticket.Expiration;

    return authCookie;
}

HTH
チャールズ

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top