#c# #asp.net-mvc #asp.net-mvc-4 #form-authentication #custom-authentication
#c# #asp.net-mvc #asp.net-mvc-4 #форма-аутентификация #пользовательская аутентификация
Вопрос:
Привет, я написал пользовательскую систему аутентификации на основе ролей для своего ASP.NET Приложение MVC.
Итак, изменения, которые мне понравились, следующие
В файл Global.asax.cs добавлен следующий метод
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
protected void FormsAuthentication_OnAuthenticate(Object sender, FormsAuthenticationEventArgs e)
{
try
{
if (FormsAuthentication.CookiesSupported == true)
{
if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
{
try
{
string username = FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value).Name;
string roles = string.Empty;
if(!string.IsNullOrEmpty(username))
{
// user --> Roles Getting from DB using Stored Procdure
roles = user.RoleName;
}
e.User = new System.Security.Principal.GenericPrincipal(
new System.Security.Principal.GenericIdentity(username, "Forms"), roles.Split(';'));
}
catch (Exception)
{
throw;
}
}
}
}
catch (Exception)
{
throw;
}
}
в Web.Config
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
в FilterConfig.cs в папке App_Start
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
}
в методе контроллера входа
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginUserViewModel loginmodel, string returnUrl)
{
try
{
UserViewModel userdata=null;
if (loginmodel.UserName != null amp; loginmodel.Password != null)
{
// Get userData via Stored Procedure
if (userdata != null)
{
FormsAuthentication.SetAuthCookie(loginmodel.UserName, false);
if (Url.IsLocalUrl(returnUrl) amp;amp; returnUrl.Length > 1 amp;amp; returnUrl.StartsWith("/")
amp;amp; !returnUrl.StartsWith("//") amp;amp; !returnUrl.StartsWith("/\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Dashboard", "Home");
}
}
else
{
ModelState.AddModelError("", "Login failed.");
}
}
else
{
ModelState.AddModelError("", "Login failed.");
}
return View(userdata);
}
catch (Exception)
{
throw;
}
}
Страница Login.cshtml
@using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
@* rest of data *@
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group ">
<div class="col-sm-12 col-lg-12 col-md-12">
<button type="submit" >Login</button>
</div>
</div>
}
Наконец, в HomeController.cs
[Authorize(Roles="admin")]
public ActionResult Dashboard()
{
//rest of fetching
}
Здесь все работало отлично, но случайно я отладил / запустил страницу просмотра панели мониторинга без входа ,
Теперь я заканчиваю со следующей ошибкой в FormsAuthentication_OnAuthenticate
методе в Global.asax
файле,
ссылка на объект не установлена для экземпляра объекта.
Теперь, когда я начинаю отлаживать этот проект, он заканчивается там
Комментарии:
1. Какая строка выдает исключение ссылки на объект внутри
FormsAuthentication_OnAuthenticate
? Кажется, что переменная пытается присвоить нулевую ссылку из другого объекта.2. @TetsuyaYamamoto выдает ошибку, подобную следующей i.imgur.com/jJb18Mi.png
Ответ №1:
ваш атрибут авторизации не использует вашу реализацию, то, что вы создали, вы действительно должны были сделать в пользовательском атрибуте AuthoriseAttribue, который наследует атрибут AuthorizeAttribute
что-то вроде этого с вашим собственным кодом, получающим роли и аутентификацию
public class AuthorizeUserAttribute : AuthorizeAttribute
{
....
//your code here
}
и тогда ваш ViewModel Model должен выглядеть следующим образом
[AuthorizeUserAttribute(Roles="admin")]
public ActionResult Dashboard()
{
//rest of fetching
}
Комментарии:
1. нужно ли мне создавать новый класс как
AuthorizeUserAttribute
?2. да, вам нужно будет. Для любых пользовательских фильтров вам нужно будет добавить новый класс, но убедитесь, что для любого используемого вами фильтра вы заканчиваете его атрибутом, а затем получаете некоторую форму наследования его базового класса
3. куда я должен поместить этот
AuthorizeUserAttribute
класс в любое конкретное местоположение?, мойDashboard
метод контроллера в классе домашнего контроллера4. Способ, которым я это делаю, — создать папку с именем filters, где все они хранятся. это помогает любому, кто смотрит на ваш код, знать, что должно быть где
5. На самом деле мне немного непонятно, вы рекомендуете создать новый вызов папки,
filters
затем создать вызов классаAuthorizeUserAttribute
внутри него, затем поместитьFormsAuthentication_OnAuthenticate
метод внутриAuthorizeUserAttribute
класса не в Global.asax ?