Разрешение на просмотр страницы только для авторизованных пользователей ASP MVC
Знаком с ASP.NET на базовом уровне, поэтому хочу спросить тут экспертного мнения.
Создал несколько View, а также Controller для работы с этими View. На одном из них происходит авторизация, а затем переадресация на страницу конкретного пользователя, где он может осуществлять какие-либо действия. Хотелось бы сделать так, чтобы пользователь не мог получить доступ к странице, пока не авторизуется в системе.
Прочитал в интернете, что для этого существует аннотация [Authorize]
Добавил ее к контроллеру, который работает со страницей пользователя. Не помогло.
Добавил ее к методу, который выводит страницу пользователя. Не помогло.
Возможно, мне что-то надо добавить в Program.cs?
Метод, который я использую при авторизации:
private async Task Authenticate(string userPhone)
{
var claim = new List<Claim> { new Claim(ClaimsIdentity.DefaultNameClaimType, userPhone) };
ClaimsIdentity id = new ClaimsIdentity(claim, "ApplicationCobokie", ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(id));
}
Метод для View:
[HttpPost]
[ValidateAntiForgeryToken]
[Route("SignIn")]
public async Task<IActionResult> SignIn(LoginModel model)
{
if (ModelState.IsValid)
{
User user = await db.Users.FirstOrDefaultAsync(c => c.PhoneNumber.Equals(model.PhoneNumber) && c.Password.Equals(model.Password));
if (user != null && user.RoleId.Equals(db.UserRoles.FirstOrDefaultAsync(x => x.RoleName.Equals("Пользователь")).Result.IdRole))
{
HttpContext.Session.SetString("AuthUser", model.PhoneNumber);
await Authenticate(model.PhoneNumber);
return RedirectToAction("UserPage", "Home");
}
if (user != null && user.RoleId.Equals(db.UserRoles.FirstOrDefaultAsync(x => x.RoleName.Equals("Администратор")).Result.IdRole))
{
HttpContext.Session.SetString("AuthUser", model.PhoneNumber);
HttpContext.Session.SetString("Admin", "True");
await Authenticate(model.PhoneNumber);
return RedirectToAction("AdminPage", "Home");
}
}
return RedirectToAction("SignIn", "Home");
Форма для авторизации:
@using WebApp.Models
@model WebApp.Models.LoginModel;
@{
Layout = null;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Вход в систему</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700" rel="stylesheet">
<link rel="stylesheet" href="/css/authpage.css" />
</head>
<!-- partial:index.partial.html -->
<body class="align">
<div class="grid">
<form asp-antiforgery="true" asp-action="SignIn" asp-controller="Registration" method="post" class="form login">
<div class="form__field">
<label for="login__username"><svg class="icon"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#user"></use></svg><span class="hidden">Username</span></label>
<input asp-for="@Model.PhoneNumber" name="PhoneNumber" id="phone" type="text" class="form__input" placeholder="Номер телефона" required>
<span asp-validation-for="PhoneNumber"></span>
</div>
<div class="form__field">
<label for="login__password"><svg class="icon"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#lock"></use></svg><span class="hidden">Password</span></label>
<input asp-for="@Model.Password" type="password" name="Password" class="form__input" placeholder="Пароль" required>
<span asp-validation-for="Password"></span>
</div>
<div class="form__field">
<input type="submit" value="Войти в систему">
</div>
</form>
<p class="text--center">Не зарегистрированы? <a asp-controller="Registration" asp-action="Registration">Создать аккаунт</a> <svg class="icon"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="assets/images/icons.svg#arrow-right"></use></svg></p>
</div>
<svg xmlns="http://www.w3.org/2000/svg" class="icons"><symbol id="arrow-right" viewBox="0 0 1792 1792"><path d="M1600 960q0 54-37 91l-651 651q-39 37-91 37-51 0-90-37l-75-75q-38-38-38-91t38-91l293-293H245q-52 0-84.5-37.5T128 1024V896q0-53 32.5-90.5T245 768h704L656 474q-38-36-38-90t38-90l75-75q38-38 90-38 53 0 91 38l651 651q37 35 37 90z" /></symbol><symbol id="lock" viewBox="0 0 1792 1792"><path d="M640 768h512V576q0-106-75-181t-181-75-181 75-75 181v192zm832 96v576q0 40-28 68t-68 28H416q-40 0-68-28t-28-68V864q0-40 28-68t68-28h32V576q0-184 132-316t316-132 316 132 132 316v192h32q40 0 68 28t28 68z" /></symbol><symbol id="user" viewBox="0 0 1792 1792"><path d="M1600 1405q0 120-73 189.5t-194 69.5H459q-121 0-194-69.5T192 1405q0-53 3.5-103.5t14-109T236 1084t43-97.5 62-81 85.5-53.5T538 832q9 0 42 21.5t74.5 48 108 48T896 971t133.5-21.5 108-48 74.5-48 42-21.5q61 0 111.5 20t85.5 53.5 62 81 43 97.5 26.5 108.5 14 109 3.5 103.5zm-320-893q0 159-112.5 271.5T896 896 624.5 783.5 512 512t112.5-271.5T896 128t271.5 112.5T1280 512z" /></symbol></svg>
</body>
</html>
Метод для отображения страницы с данными конкретного пользователя:
[Authorize]
[Route("MyPackages")]
public IActionResult PackagesWindow()
{
List<Package> packages = new List<Package>();
var queryList = db.PackagesOfUsers.ToList();
var allUsers = db.Users.ToList();
foreach (var elem in queryList)
{
if (elem.UserId.Equals(allUsers.FirstOrDefault(x => x.PhoneNumber.Equals(HttpContext.Session.GetString("AuthUser"))).IdUser))
{
packages.Add(db.Packages.FirstOrDefault(x => x.IdPackage.Equals(elem.PackageId)));
}
}
return View(packages);
}
Ответы (1 шт):
Предположу что у вас не настроена система Аутентификации/Авторизации.
Так что давайте настроим ее:
В вашем Program.cs зарегистрируйте сервис для авторизации:
builder.Services.AddAuthorization();
Далее настроим простую схему аутентификации и авторизации с помощью кук (Для JWT она будет различатся)
builder.Services.AddAuthentication(auth =>
{
auth.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
auth.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(cookie =>
{
cookie.Cookie.SameSite = SameSiteMode.Strict;
cookie.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
Далее нужно установить порядок middleware для правильной аутентификации/авторизации:
Настройка порядка middleware, начинается с этой строчки :
var app = builder.Build();
Добавим нужные middleware для аутентификации/авторизации:
app.UseAuthentication();
app.UseAuthorization();
Обычно эти 2 middleware размещаются почти в самом конце очереди, после них могут идти только кастомные middleware, или же app.MapControllerRoute
Далее можете цеплять аттрибуты [Authorize] на те эндпоинты и контроллеры, которые вы хотите защитить от неавторизованного доступа
Ну и еще отмечу что в этом аттрибуте можно настраивать роли, т.е указать с какими ролями юзеры могут иметь доступ к эндпоинту или же контроллеру, делается это так:
[Authorize(Roles = "HighestAdmin")]
Если нужно указать несколько ролей:
[Authorize(Roles = "HighestAdmin,Admin")]
Помните что порядок middleware имеет значение, вам нужно в праввильном порядке их зарегистрировать: https://learn.microsoft.com/ru-ru/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0#middleware-order
P.S: Чего-то вы намудрили в эндпоинте входа, советую провести рефакторинг данного участка кода.