Имам задача да създам потребител само за четене за нашето приложение ASP.Net MVC3. т.е. те могат да влизат, да преглеждат всички данни, но не могат да актуализират никакви данни.
Прочетох много статии/рамки за удостоверяване, като тази: Внедрете защитени ASP.NET MVC приложения или Fluent Security Configuration или Създаване на филтри за действие в ASP.Net MVC (и няколко други, към които вече загубих връзки).
Проблемът с повечето от подходите е, че изискват драстични промени в домейна/приложението. И имам само един ден за прилагане на функцията.
Имаме около сто контролера със средно 4 действия на контролер (предимно CRUD операции) и преминаването през всеки един от тях е изключено. Също така би било лесно да забравите да поставите атрибути в новия код - въвеждане на грешки.
Досега измислих глобален филтър, който отрича всички базирани на POST действия и действия на контролера, наречени „Създаване“ за потребител само за четене:
public class ReadOnlyFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext filterContext)
{
var currentUser = HttpContext.Current.User;
if (currentUser == null || !currentUser.Identity.IsAuthenticated)
return; // user is not logged in yet
if (!currentUser.IsInRole("Readonly"))
return; // user is not read-only. Nothing to see here, move on!
// Presume User is read-only from now on.
// if action is of type post - deny
if (filterContext.HttpContext.Request.HttpMethod.ToUpper() == "POST")
{
filterContext.HttpContext.Response.Redirect("~/ReadOnlyAccess");
}
// if action is "Create" - deny access
if (filterContext.ActionDescriptor.ActionName == "Create")
{
filterContext.HttpContext.Response.Redirect("~/ReadOnlyAccess");
}
// if action is edit - check if Details action exits -> redirect to it.
//TODO get this done ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
return;
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
// blah! have to have this here for IActionFilter
}
}
Следващото нещо, което планирам да създам атрибут [AllowReadOnlyUser] за действия по публикуване, като промяна на парола/имейл, и във филтъра да позволя това действие да премине.
Чудя се дали има по-добри начини да се направят подобни неща?
Актуализация: Приложението не е за обществено ползване. Използва се в корпоративния свят за проследяване на хора, активи и други скучни данни.
Актуализация 2: Изглежда съм приключил с тази задача. Направи го като контролер, както започна. Пълен код и малко обяснение, което можете да видите в моя блог.