Идентификатор.NET Core как регистр отмены пользовательского интерфейса
Я хочу отменить параметр "Регистрация" в.NET Core 2.1 + Identity в качестве приложения пользовательского интерфейса.
Я могу, конечно, просто удалить кнопку со страницы, вопрос - это безопасно?
Если нет, то каковы мои другие варианты? следует ли использовать строительные леса для создания кода регистра, а затем отключить его там?
(то же самое относится к SetPassword и т.д.)
Спасибо
Ответы
Ответ 1
Для веб-страниц ASP.NET это дополнение для ответа ранее, чтобы включить веб-страницы бритвы ASP.Net. Я разделил их, как если бы кто-то нуждался в них, а не путался друг с другом. Веб-страницы отличаются тем, что включают в себя код, как и веб-формы.
Сначала вы будете редактировать страницы> _LoginPartial.cshtml
Удалить строку <li><a asp-page="/Account/Register">Register</a></li>
Далее отредактируйте страницы> Аккаунт> Login.cshtml. Удалите следующее:
<div class="form-group">
<p>
<a asp-page="./ForgotPassword">Forgot your password?</a>
</p>
<p>
<a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
</p>
</div>
Также удалите:
<div class="col-md-6 col-md-offset-2">
<section>
<h4>Use another service to log in.</h4>
<hr />
@{
if ((Model.ExternalLogins?.Count ?? 0) == 0)
{
<div>
<p>
There are no external authentication services configured. See <a href="https://go.microsoft.com/fwlink/?LinkID=532715">this article</a>
for details on setting up this ASP.NET application to support logging in via external services.
</p>
</div>
}
else
{
<form asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
<div>
<p>
@foreach (var provider in Model.ExternalLogins)
{
<button type="submit" class="btn btn-default" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">@provider.DisplayName</button>
}
</p>
</div>
</form>
}
}
</section>
</div>
Теперь отредактируйте код позади Login.cshtml.cs
Удалить:
public IList<AuthenticationScheme> ExternalLogins { get; set; }
Также удалить:
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
Изменить страницы> Аккаунт> Управление> _ManageNav.cshtml
Удалить:
@if (hasExternalLogins)
{
<li class="@ManageNavPages.ExternalLoginsNavClass(ViewContext)"><a asp-page="./ExternalLogins">External logins</a></li>
}
Далее мы удалим следующие файлы из каталога Pages> Account:
- ExternalLogin.cshtml
- ForgotPassword.cshtml
- ForgotPasswordConfirmation.cshtml
- Register.cshtml
- ResetPassword.cshtml
- ResetPasswordConfirmation.cshtml
Удалите следующие файлы из каталога Pages> Account> Manage:
Ответ 2
К сожалению, два других ответа неверны - вопрос на самом деле относится к новому расширению AddDefaultIdentity(), которое использует страницы Razor для обслуживания пользовательского интерфейса по умолчанию. Ответ, который касается этого, не удалит функциональность регистра, как было запрошено в вопросе.
Фон
AddDefaultIdentity работает аналогично AddIdentity, но также включает вызов AddDefaultUI, который предоставляет вашему приложению доступ к новым представлениям бритвы Identity (в настоящее время их 28), которые находятся в новой библиотеке классов бритвы. Обратите внимание, что это не единственное различие между AddDefaultIdentity и AddIdentity (см. Далее).
Чтобы изменить представления по умолчанию, вам необходимо переопределить ("scaffold") представления в вашем проекте, а затем вы можете изменить их. Если вы не переопределите представления, или если вы переопределите их, а затем удалите файлы cshtml, вы просто вернетесь к версиям пользовательского интерфейса по умолчанию! Даже если вы удалите ссылки, например, зарегистрироваться, пользователь все равно сможет перейти к представлению реестра по умолчанию, если он угадает URL.
Вариант 1 - переопределить представления
Если вы хотите сохранить некоторые из представлений по умолчанию и изменить или удалить другие, вы можете переопределить представления следующим образом (из этого документа):
- Щелкните правой кнопкой мыши свой проект> Добавить> Новый элемент лесов.
- На левой панели диалога Add Scaffold выберите Identity> Add
- В диалоговом окне "Добавить удостоверение" выберите нужные параметры.
Теперь вы можете либо просто изменить внешний вид и функциональность переопределенного представления, либо "удалить" его, чтобы оно вернуло 404 или перенаправило куда-то еще. Если вы удалите это переопределенное представление, пользовательский интерфейс по умолчанию вернется!
Этот подход может быстро запутаться, если вы хотите переопределить все представления.
Вариант 2 - не добавлять интерфейс по умолчанию
Другой вариант - вернуться к старому способу добавления идентификаторов, который не вызывает AddDefaultUI. Недостатком является то, что вам нужно будет добавить все представления самостоятельно. Вы можете сделать это следующим образом (из этого документа - хотя игнорируйте первую строку о переопределении всех представлений, которая применяется к варианту 1 выше):
//remove this: services.AddDefaultIdentity<IdentityUser>()
//use this instead to get the Identity basics without any default UI:
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
//this assumes you want to continue using razor views for your identity UI
//it specifies areas can be used with razor pages and then adds an
//authorize filter with a default policy for the folder /Account/Manage and
//the page /Account/Logout.cshtml (both of which live in Areas/Identity/Pages)
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddRazorPagesOptions(options =>
{
options.AllowAreas = true;
options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
});
//configures the application cookie to redirect on challenge, etc.
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = $"/Identity/Account/Login";
options.LogoutPath = $"/Identity/Account/Logout";
options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});
//configures an email sender for e.g. password resets
services.AddSingleton<IEmailSender, EmailSender>();
Обратите внимание, что я не уверен на 100%, что этот второй подход также без проблем, как упоминалось выше, есть и другие различия между AddDefaultIdentity и AddIdentity. Например, последний добавляет сервис RoleManager, а первый - нет. Кроме того, мне неясно, будут ли оба эти подхода поддерживаться и поддерживаться в равной степени в будущем.
Если вы сомневаетесь в том, что делают вышеупомянутые опции (и если у вас есть несколько часов, чтобы убить), вы можете посмотреть на источник для AddDefaultIdentity (который также вызывает AddIdentityCookies и AddIdentityCore) по сравнению со старым AddIdentity.
Вариант 3 - Гибридный подход
Наилучшим вариантом в настоящее время является, вероятно, объединение предыдущих 2 следующим образом:
- Настройте свой проект на использование идентификатора по умолчанию
- Поместите только те представления, которые вы хотите включить, и отредактируйте их соответственно
- Переключитесь на старый вызов AddIdentity и включите параметры бритвы, как показано в варианте 2 (при необходимости корректируя в зависимости от того, какие виды вы включили
Теперь у вас есть только те представления, которые вы хотите, и они основаны на реализациях по умолчанию, что означает, что большая часть работы для вас выполнена для этих представлений.
Ответ 3
Я предполагаю, что вы говорите о веб-приложении Model-View-Controller. Я могу сказать вам, что небезопасно просто удалить кнопку или даже взгляды на такие.
Я также предполагаю, что вы хотели бы удалить сторонний логин, который также создал бы зарегистрированного пользователя.
Я бы сделал следующее:
В вашем контроллере аккаунта удалите следующие
[HttpGet]
[AllowAnonymous]
public IActionResult Register(string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme);
await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl);
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation("User created a new account with password.");
return RedirectToLocal(returnUrl);
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
Также в диспетчере учетных записей далее снимите следующее:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public IActionResult ExternalLogin(string provider, string returnUrl = null)
{
// Request a redirect to the external login provider.
var redirectUrl = Url.Action(nameof(ExternalLoginCallback), "Account", new { returnUrl });
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return Challenge(properties, provider);
}
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
if (remoteError != null)
{
ErrorMessage = $"Error from external provider: {remoteError}";
return RedirectToAction(nameof(Login));
}
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
return RedirectToAction(nameof(Login));
}
// Sign in the user with this external login provider if the user already has a login.
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
if (result.Succeeded)
{
_logger.LogInformation("User logged in with {Name} provider.", info.LoginProvider);
return RedirectToLocal(returnUrl);
}
if (result.IsLockedOut)
{
return RedirectToAction(nameof(Lockout));
}
else
{
// If the user does not have an account, then ask the user to create an account.
ViewData["ReturnUrl"] = returnUrl;
ViewData["LoginProvider"] = info.LoginProvider;
var email = info.Principal.FindFirstValue(ClaimTypes.Email);
return View("ExternalLogin", new ExternalLoginViewModel { Email = email });
}
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ExternalLoginConfirmation(ExternalLoginViewModel model, string returnUrl = null)
{
if (ModelState.IsValid)
{
// Get the information about the user from the external login provider
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
throw new ApplicationException("Error loading external login information during confirmation.");
}
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await _userManager.CreateAsync(user);
if (result.Succeeded)
{
result = await _userManager.AddLoginAsync(user, info);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider);
return RedirectToLocal(returnUrl);
}
}
AddErrors(result);
}
ViewData["ReturnUrl"] = returnUrl;
return View(nameof(ExternalLogin), model);
}
также удалять
[HttpGet]
[AllowAnonymous]
public IActionResult ForgotPassword()
{
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
if (ModelState.IsValid)
{
var user = await _userManager.FindByEmailAsync(model.Email);
if (user == null || !(await _userManager.IsEmailConfirmedAsync(user)))
{
// Don't reveal that the user does not exist or is not confirmed
return RedirectToAction(nameof(ForgotPasswordConfirmation));
}
// For more information on how to enable account confirmation and password reset please
// visit https://go.microsoft.com/fwlink/?LinkID=532713
var code = await _userManager.GeneratePasswordResetTokenAsync(user);
var callbackUrl = Url.ResetPasswordCallbackLink(user.Id, code, Request.Scheme);
await _emailSender.SendEmailAsync(model.Email, "Reset Password",
$"Please reset your password by clicking here: <a href='{callbackUrl}'>link</a>");
return RedirectToAction(nameof(ForgotPasswordConfirmation));
}
// If we got this far, something failed, redisplay form
return View(model);
}
[HttpGet]
[AllowAnonymous]
public IActionResult ForgotPasswordConfirmation()
{
return View();
}
[HttpGet]
[AllowAnonymous]
public IActionResult ResetPassword(string code = null)
{
if (code == null)
{
throw new ApplicationException("A code must be supplied for password reset.");
}
var model = new ResetPasswordViewModel { Code = code };
return View(model);
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ResetPassword(ResetPasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await _userManager.FindByEmailAsync(model.Email);
if (user == null)
{
// Don't reveal that the user does not exist
return RedirectToAction(nameof(ResetPasswordConfirmation));
}
var result = await _userManager.ResetPasswordAsync(user, model.Code, model.Password);
if (result.Succeeded)
{
return RedirectToAction(nameof(ResetPasswordConfirmation));
}
AddErrors(result);
return View();
}
[HttpGet]
[AllowAnonymous]
public IActionResult ResetPasswordConfirmation()
{
return View();
}
Теперь в разделе "Модели" вы можете удалить следующие файлы:
- ExternalLoginViewModel
- ForgotPasswordViewModel
- RegisterViewModel
- ResetPasswordViewModel
В разделе "Виды" я удалю:
- Подтвердите адрес электронной почты
- ExternalLogin
- Забыли пароль
- ForgotPasswordConfirmation
- регистр
- Сброс пароля
- ResetPasswordConfirmation
Также в разделе "Просмотр учетных записей" отредактируйте "Login.cshtml" и удалите следующее:
<div class="form-group">
<p>
<a asp-page="./ForgotPassword">Forgot your password?</a>
</p>
<p>
<a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
</p>
</div>
Также удалите:
<div class="col-md-6 col-md-offset-2">
<section>
<h4>Use another service to log in.</h4>
<hr />
@{
if ((Model.ExternalLogins?.Count ?? 0) == 0)
{
<div>
<p>
There are no external authentication services configured. See <a href="#" onclick="location.href='https://go.microsoft.com/fwlink/?LinkID=532715'; return false;">this article</a>
for details on setting up this ASP.NET application to support logging in via external services.
</p>
</div>
}
else
{
<form asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
<div>
<p>
@foreach (var provider in Model.ExternalLogins)
{
<button type="submit" class="btn btn-default" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">@provider.DisplayName</button>
}
</p>
</div>
</form>
}
}
</section>
</div>
Теперь под вашими общими представлениями откройте _LoginPartial.cshtml и удалите следующее:
<li><a asp-area="" asp-controller="Account" asp-action="Register">Register</a></li>
В разделе Manage Views _ManageNav.cshtml удалите следующее:
@if (hasExternalLogins)
{
<li class="@ManageNavPages.ExternalLoginsNavClass(ViewContext)"><a asp-action="ExternalLogins">External logins</a></li>
}
Теперь, даже если вы перейдете на URL-адрес yourapp.com/Account/Register, вы получите страницу 404.
Надеюсь это поможет.