ASP.NET MVCカスタム認証
-
07-07-2019 - |
質問
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
チャールズ