Идентификатор.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:

  • ExternalLogin.cshtml

Ответ 2

К сожалению, два других ответа неверны - вопрос на самом деле относится к новому расширению AddDefaultIdentity(), которое использует страницы Razor для обслуживания пользовательского интерфейса по умолчанию. Ответ, который касается этого, не удалит функциональность регистра, как было запрошено в вопросе.

Фон

AddDefaultIdentity работает аналогично AddIdentity, но также включает вызов AddDefaultUI, который предоставляет вашему приложению доступ к новым представлениям бритвы Identity (в настоящее время их 28), которые находятся в новой библиотеке классов бритвы. Обратите внимание, что это не единственное различие между AddDefaultIdentity и AddIdentity (см. Далее).

Чтобы изменить представления по умолчанию, вам необходимо переопределить ("scaffold") представления в вашем проекте, а затем вы можете изменить их. Если вы не переопределите представления, или если вы переопределите их, а затем удалите файлы cshtml, вы просто вернетесь к версиям пользовательского интерфейса по умолчанию! Даже если вы удалите ссылки, например, зарегистрироваться, пользователь все равно сможет перейти к представлению реестра по умолчанию, если он угадает URL.

Вариант 1 - переопределить представления

Если вы хотите сохранить некоторые из представлений по умолчанию и изменить или удалить другие, вы можете переопределить представления следующим образом (из этого документа):

  1. Щелкните правой кнопкой мыши свой проект> Добавить> Новый элемент лесов.
  2. На левой панели диалога Add Scaffold выберите Identity> Add
  3. В диалоговом окне "Добавить удостоверение" выберите нужные параметры.

Теперь вы можете либо просто изменить внешний вид и функциональность переопределенного представления, либо "удалить" его, чтобы оно вернуло 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 следующим образом:

  1. Настройте свой проект на использование идентификатора по умолчанию
  2. Поместите только те представления, которые вы хотите включить, и отредактируйте их соответственно
  3. Переключитесь на старый вызов 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.

Надеюсь это поможет.