Я занимаюсь разработкой приложения Asp.Net MVC с FormsAuthentication. Проверки формы выполняются в jquery и jquery, а затем в методе действия $ .post to MVC. Каждый запрос проверяется этим классом:
[Serializable]
public class CachedModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
object model = base.BindModel(controllerContext, bindingContext);
HelperMethods.ValidateLogin(controllerContext.HttpContext.Session, controllerContext.HttpContext.User.Identity.IsAuthenticated, controllerContext.HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName], (BaseViewModel)model, controllerContext.HttpContext.Request.Url.AbsoluteUri, controllerContext.HttpContext);
return model;
}
}
public static bool ValidateLogin(HttpSessionStateBase session, bool is_authenticated, HttpCookie authCookie, BaseViewModel model, string Uri, HttpContextBase context)
{
if (session != null)
{
if (session["ResId"] == null || !is_authenticated)
{
if (is_authenticated)
FormsAuthentication.SignOut();
if (session["ResId"] != null)
session["ResId"] = null;
return false;
}
else
{
LoadRestaurant(authCookie, model);
return true;
}
}
else
{
return false;
}
}
Я не уверен, как этот метод запущен, и я не вижу стека вызовов до этого метода. Может кто-нибудь сказать мне, как это называется? У меня есть три класса viewmodel (BaseModel, HomeModel, RestaurantModel) для двух представлений (Home / Index.cshtml и Business / Index.cshtml)
Так я регистрирую модели в файле global.asax.cs. Я не регистрирую BaseModel ниже, потому что он не передается в качестве входных данных для любого из методов действия.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
XmlConfigurator.Configure();
ModelBinders.Binders.Add(typeof(HomeModel), new CachedModelBinder());
ModelBinders.Binders.Add(typeof(RestaurantModel), new CachedModelBinder());
}
Код модели выглядит следующим образом
public class BaseModel
{
public bool IsAuthenticated { get; set; }
public string PageTitle { get; set; }
public string UserName { get; set; }
public string Password{ get; set; }
public Business Business { get; set; }
public int BusinessId { get; set; }
}
public class HomeModel : BaseModel
{
}
public class RestaurantModel : BaseModel
{
public int RestaurantId { get; set; }
public string RestaurantEmail { get; set; }
public Business Restaurant{ get; set; }
}
HomeController.cs ->
public ActionResult Index(HomeModel model)
{
if (model.IsAuthenticated) { return RedirectToAction("Index", "Restaurant"); }
// code goes here
return View(model);
}
[ControllerLogInterceptor]
public ActionResult Login(HomeModel model)
{
// Login verification code goes here
FormsAuthentication.SetAuthCookie(res.ID.ToString(), false);
Session["ResId"] = bus.ID;
return Json;
}
RestaurantController.cs ->
public ActionResult Index(RestaurantModel model)
{
if (model.Business == null || model.Business.ID < 1)
{
FormsAuthentication.SignOut();
RedirectToAction("Index", "Home");
}
else
{
// next view code goes here
}
return View(model);
}
jQuery / HTML-код
<form id="loginForm" method="post">
<div class="form-group">
<input type="text" id="UserName" name="UserName" class="form-control col-sm-3" />
<div class="invalid-feedback" id="validationFileNumber">
<span>UserName is required</span>
</div>
</div>
<div class="form-group">
<input type="text" id="Password" name="Password" class="form-control col-sm-1" />
<div class="invalid-feedback" id="validationPin">
<span>Password is required</span>
</div>
</div>
<span class="invalid-feedback" id="divError"><br /></span>
<button type="submit" class="btn btn-primary disabled" id="btnLogin">Continue</button>
<input type="text" class="form-group valid-feedback">
</form>
$('#btnLogin').click(function () {
// Form validation happens before
var model = $('#loginForm').serialize();
$.post('/Home/Login', model)
.done(function (response, status, jqXhr) {
window.location = '/Restaurant';
}
})
.fail(function (response, status, jqXhr) {
})
});
После успешного входа в систему метод BindModel снова вызывается с HomeModel и не проходит проверку подлинности. Также метод bindModel вызывается дважды.
Приложение должно аутентифицировать пользователя для других страниц.