Проверка подлинности .NET Core Identity Server 4 VS проверка подлинности

92

Я пытаюсь понять, как правильно выполнять аутентификацию в ASP.NET Core. Я просмотрел несколько ресурсов (большинство из которых устарели).

Некоторые люди предоставляют альтернативные решения, в которых говорится об использовании облачного решения, такого как Azure AD, или об использовании IdentityServer4 и размещении моего собственного Token Server.

В старой версии .Net одной из более простых форм аутентификации было бы создание Custom Iprinciple и хранение дополнительных данных пользователя аутентификации внутри.

public interface ICustomPrincipal : System.Security.Principal.IPrincipal
{
    string FirstName { get; set; }

    string LastName { get; set; }
}

public class CustomPrincipal : ICustomPrincipal
{
    public IIdentity Identity { get; private set; }

    public CustomPrincipal(string username)
    {
        this.Identity = new GenericIdentity(username);
    }

    public bool IsInRole(string role)
    {
        return Identity != null && Identity.IsAuthenticated && 
           !string.IsNullOrWhiteSpace(role) && Roles.IsUserInRole(Identity.Name, role);
    }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string FullName { get { return FirstName + " " + LastName; } }
}

public class CustomPrincipalSerializedModel
{
    public int Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }
}

Затем вы должны сериализовать свои данные в cookie и вернуть их клиенту.

public void CreateAuthenticationTicket(string username) {     

    var authUser = Repository.Find(u => u.Username == username);  
    CustomPrincipalSerializedModel serializeModel = new CustomPrincipalSerializedModel();

    serializeModel.FirstName = authUser.FirstName;
    serializeModel.LastName = authUser.LastName;
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    string userData = serializer.Serialize(serializeModel);

    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
    1,username,DateTime.Now,DateTime.Now.AddHours(8),false,userData);
    string encTicket = FormsAuthentication.Encrypt(authTicket);
    HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
    Response.Cookies.Add(faCookie);
}

Мои вопросы:

  1. Как я могу пройти аутентификацию аналогично тому, как это было сделано в предыдущей версии .Net, работает ли старый способ или есть более новая версия.

  2. Каковы плюсы и минусы использования ваших собственных стихов токен-сервера для создания собственного пользовательского принципа?

  3. При использовании облачного решения или отдельного сервера токенов, как бы вы интегрировали это с вашим текущим приложением, нужна ли мне таблица пользователей в моем приложении, как бы вы связали их?

  4. Поскольку существует так много различных решений, как я могу создать корпоративное приложение, позволяющее входить в систему через Gmail / Facebook, при этом имея возможность расширяться до других систем единого входа

  5. Какие простые реализации этих технологий?
Джонни 5
источник
Этот вопрос слишком общий и в значительной степени основан на мнениях. Либо существует слишком много возможных ответов, либо хорошие ответы будут слишком длинными для этого формата. Добавьте подробности, чтобы сузить набор ответов или выделить проблему, на которую можно ответить в нескольких абзацах. Многие хорошие вопросы порождают определенную степень мнения, основанного на опыте экспертов, но ответы на этот вопрос, как правило, почти полностью основываются на мнениях, а не на фактах, ссылках или конкретном опыте.
Nkosi
@Nkosi извини, что фраза была такой. Я уточнил это, чтобы быть более конкретным
johnny 5

Ответы:

145

TL; DR

IdentityServer = службы шифрования и проверки токенов через OAuth 2.0 / OpenId-Connect

ASP.NET Identity = текущая стратегия управления идентификацией в ASP.NET

Как я могу пройти аутентификацию аналогично тому, как это было сделано в предыдущей версии .Net, работает ли старый способ или есть более новая версия.

Я не вижу причин, по которым вы не могли достичь старого пути в ASP.NET Core, но в целом эта стратегия была заменена на ASP.NET Identity, а ASP.NET Identity жив и здоров в ASP.NET Core.

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity

ASP.NET Identity использует резервное хранилище, такое как SQL Server, для хранения пользовательской информации, такой как имя пользователя, пароль (хешированный), электронная почта, телефон, и легко расширяется для хранения FirstName, LastName или чего-то еще. Таким образом, действительно нет причин для шифрования пользовательской информации в cookie и передачи ее от клиента к серверу. Он поддерживает такие понятия, как утверждения пользователей, токены пользователей, роли пользователей и внешние логины. Вот сущности в ASP.NET Identity:

  • AspNetUsers
  • AspNetUserRoles
  • AspNetUserClaims
  • AspNetUserLogins (для связывания внешних поставщиков удостоверений, таких как Google, AAD)
  • AspNetUserTokens (для хранения таких вещей, как access_tokens и refresh_tokens, накопленных пользователем)

Каковы плюсы и минусы использования ваших собственных стихов токен-сервера для создания собственного пользовательского принципа?

Токен-сервер - это система, которая генерирует простую структуру данных, содержащую информацию об авторизации и / или аутентификации. Для авторизации обычно используется токен с именем access_token . Это будут, так сказать, «ключи от дома», позволяющие вам пройти через дверной проем и попасть в резиденцию защищенного ресурса, обычно веб-api. Для аутентификации id_tokenсодержит уникальный идентификатор пользователя / человека. Хотя обычно такой идентификатор помещают в access_token, теперь для этого существует специальный протокол: OpenID-Connect .

Причина, по которой ваша собственная служба токенов безопасности (STS) должна состоять в том, чтобы защитить ваши информационные активы с помощью криптографии и контролировать, какие клиенты (приложения) могут получить доступ к этим ресурсам. Более того, стандарты управления идентификацией теперь существуют в спецификациях OpenID-Connect. IdentityServer - это пример сервера авторизации OAuth 2.0 в сочетании с сервером аутентификации OpenID-Connect.

Но ничего из этого не требуется, если вам просто нужна таблица пользователей в вашем приложении. Вам не нужен токен-сервер - просто используйте ASP.NET Identity. ASP.NET Identity сопоставляет вашего пользователя с объектом ClaimsIdentity на сервере - нет необходимости в настраиваемом классе IPrincipal.

При использовании облачного решения или отдельного сервера токенов, как бы вы интегрировали это с вашим текущим приложением, нужна ли мне таблица пользователей в моем приложении, как бы вы связали их?

См. Эти руководства по интеграции отдельных решений идентификации с приложением: https://identityserver4.readthedocs.io/en/latest/quickstarts/0_overview.html https://auth0.com/docs/quickstart/webapp/aspnet-core

Как минимум, вам потребуется таблица из двух столбцов, сопоставляющая имя пользователя с идентификатором пользователя внешнего поставщика. Это то, что делает таблица AspNetUserLogins в ASP.NET Identity. Однако строки в этой таблице зависят от того, является ли запись пользователя в AspNetUsers.

ASP.NET Identity поддерживает внешних поставщиков, таких как Google, Microsoft, Facebook, любой поставщик OpenID-Connect, Azure AD уже есть. (Google и Microsoft уже внедрили протокол OpenID-Connect, поэтому вам также не нужны их пользовательские пакеты интеграции, такие как , например, этот). Кроме того, ADFS еще не доступен в ASP.NET Core Identity.

См. Этот документ, чтобы начать работу с внешними поставщиками в ASP.NET Identity:

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/

Поскольку существует так много различных решений, как я могу создать корпоративное приложение, позволяющее входить в систему через Gmail / Facebook, при этом имея возможность расширяться до других систем единого входа

Как объяснялось выше, ASP.NET Identity уже делает это. Довольно легко создать таблицу «Внешние поставщики», и данные будут управлять вашим внешним процессом входа в систему. Поэтому, когда появится новый «SSO», просто добавьте новую строку со свойствами, такими как URL-адрес поставщика, идентификатор клиента и секрет, которые они вам предоставят. В ASP.NET Identity уже есть встроенный пользовательский интерфейс в шаблонах Visual Studio, но см. « Вход в социальную сеть» для более крутых кнопок.

Резюме

Если вам просто нужна таблица пользователей с возможностью входа в систему с помощью пароля и профиль пользователя, тогда ASP.NET Identity идеально подходит. Нет необходимости привлекать внешние органы. Но если есть много приложений, которым требуется доступ ко многим API, тогда имеет смысл использовать независимый орган для защиты и проверки личности и токенов доступа. IdentityServer хорошо подходит, или см. Openiddict-core или Auth0 для облачного решения.

Мои извинения, это не попадает в цель или слишком вводно. Не стесняйтесь взаимодействовать, чтобы попасть в цель, которую вы ищете.

Приложение: аутентификация файлов cookie

Чтобы выполнить аутентификацию с использованием файлов cookie, выполните следующие действия. Но, насколько мне известно, пользовательский принципал утверждений не поддерживается. Чтобы добиться того же эффекта, используйте список утверждений ClaimPrincipalобъекта.

Создайте новое веб-приложение ASP.NET Core 1.1 в Visual Studio 2015/2017, выбрав в диалоговом окне «Без аутентификации». Затем добавьте пакет:

Microsoft.AspNetCore.Authentication.Cookies

Согласно действующему Configureметоду Startup.csэто (ранее app.UseMvc):

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationScheme = "MyCookieMiddlewareInstance",
    LoginPath = new PathString("/Controller/Login/"),
    AutomaticAuthenticate = true,
    AutomaticChallenge = true
});

Затем создайте пользовательский интерфейс входа в систему и опубликуйте HTML-форму в методе действий следующим образом:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(String username, String password, String returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;
    if (ModelState.IsValid)
    {
        // check user's password hash in database
        // retrieve user info

        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, username),
            new Claim("FirstName", "Alice"),
            new Claim("LastName", "Smith")
        };

        var identity = new ClaimsIdentity(claims, "Password");

        var principal = new ClaimsPrincipal(identity);

        await HttpContext.Authentication.SignInAsync("MyCookieMiddlewareInstance", principal);

        return RedirectToLocal(returnUrl);
    }

    ModelState.AddModelError(String.Empty, "Invalid login attempt.");

    return View();
}

Объект HttpContext.User должен иметь ваши настраиваемые утверждения и легко извлекаться из коллекции List объекта ClaimPrincipal.

Я надеюсь, что этого достаточно, поскольку полное решение / проект кажется немного большим для публикации StackOverflow.

travis.js
источник
1
Покажите, пожалуйста, пример реализации аутентификации в ядре
johnny 5
2
В документации по ASP.NET Core показан канонический пример: docs.microsoft.com/en-us/aspnet/core/security/authentication/… .
travis.js
Если можно, выложите, пожалуйста, простой пример аутентификации. Без ссылки, чтобы у людей был доступ к ресурсу, я опубликую подробный ответ о том, как настроить IdentityServer4
johnny 5
Для IdentityServer есть ли здесь тот пример, который вы ищете: identityserver4.readthedocs.io/en/dev/quickstarts/… ?
travis.js 01
Разве это не пример для ASP.NET Identity, или то, что вы говорите, устарело? docs.microsoft.com/en-us/aspnet/core/security/authentication/…
travis.js 01
11

TL; DR

Я действительно хотел бы показать полную публикацию о том, как правильно реализовать IdentityServer4, но я попытался уместить весь текст, но это было за пределами того, что принимает StackOverflow, поэтому вместо этого я исправлю некоторые советы и вещи, которые я узнал.

Каковы преимущества использования сервера токенов по сравнению с идентификатором ASP?

Токен-сервер имеет много преимуществ, но подходит не всем. Если вы внедряете корпоративное решение, где вы хотите, чтобы несколько клиентов могли входить в систему, сервер токенов - ваш лучший выбор, но если вы просто создаете простой веб-сайт, который хочет поддерживать внешние входы, вы можете уйти с ASP Identity и некоторое промежуточное ПО.

Identity Server 4 совета

Identity server 4 довольно хорошо документирован по сравнению с множеством других фреймворков, которые я видел, но трудно начать с нуля и увидеть всю картину.

Моя первая ошибка заключалась в попытке использовать OAuth в качестве аутентификации. Да, есть способы сделать это, но OAuth предназначен для авторизации, а не аутентификации, если вы хотите аутентифицировать, используйте OpenIdConnect (OIDC)

В моем случае я хотел создать клиент javascript, который подключается к веб-API. Я просмотрел множество решений, но сначала я попытался использовать webapi для вызова аутентификации на сервере идентификации и просто хотел, чтобы этот токен сохранялся, потому что он был проверен на сервере. Потенциально этот поток может работать, но у него много недостатков.

Наконец, правильный поток. Когда я нашел образец клиента Javascript, я получил правильный поток. Ваш клиент входит в систему и устанавливает токен. Затем ваш веб-API использует клиент OIdc, который проверяет ваш токен доступа к IdentityServer.

Подключение к магазинам и миграции Сначала у меня было несколько неправильных представлений о миграции. У меня сложилось впечатление, что при выполнении миграции SQL генерируется из dll внутри, вместо того, чтобы использовать настроенный вами контекст, чтобы выяснить, как создать SQL.

Существует два синтаксиса для миграции, поэтому важно знать, какой из них использует ваш компьютер:

dotnet ef migrations add InitialIdentityServerMigration -c ApplicationDbContext

Add-Migration InitialIdentityServerDbMigration -c ApplicationDbContext

Я думаю, что параметр после миграции - это имя, почему вам нужно имя, я не уверен, ApplicationDbContextэто DbContext с первым кодом, в котором вы хотите создать.

Миграции используют некоторую автоматическую магию, чтобы найти вашу строку подключения, исходя из того, как настроен ваш запуск, я просто предположил, что он использовал соединение из Server Explorer.

Если у вас несколько проектов, убедитесь, что у вас есть проект с ApplicationDbContext, установленным в качестве запуска.

При реализации авторизации и аутентификации есть много движущихся частей. Надеюсь, этот пост кому-то поможет. Самый простой способ полностью понять аутентификацию - разобрать их примеры, собрать все вместе и убедиться, что вы прочитали документацию.

Джонни 5
источник
имя после добавления-миграции - это ссылка, относящаяся к вашему выпуску / внесенным вами изменениям. то же имя будет использоваться для добавления скрипта миграции Up & Down.
Джей
@Jay Спасибо за это разъяснение
johnny 5
Конфигурация db-контекста сервера идентификации по-прежнему не так хороша, как IdentityDbContext. создание нестандартной реализации - это боль. Identityserver 4 сейчас не очень активен для выпуска новых обновлений после обновлений .core.
Джей
3

ASP.NET Identity - это сборка для аутентификации вашего приложения, будь то носитель или базовая аутентификация. Она дает нам готовый код для выполнения регистрации пользователя, входа в систему, изменения пароля и всего остального.

Теперь представьте, что у нас есть 10 разных приложений, и невозможно сделать одно и то же во всех 10 приложениях. это очень хрупкая и очень плохая практика.

Чтобы решить эту проблему, мы можем централизовать нашу аутентификацию и авторизацию, чтобы любое изменение не повлияло на все наши 10 приложений.

Сервер идентификации предоставляет вам возможность сделать то же самое. мы можем создать один образец веб-приложения, которое просто использовалось как служба идентификации, и оно проверит вашего пользователя и предоставит некоторый токен доступа JWT.

Амол Ахер
источник
2

Я всегда использовал встроенную авторизацию / аутентификацию ASP.NET Identity (и ранее - членство), я недавно реализовал Auth0 ( https://auth0.com ) и рекомендую это как что-то еще, чтобы попробовать.

Марк Редман
источник
Пример ядра Auth0 .net довольно быстро и просто реализовать, но использование всех функций требует изрядной работы, я реализовал Auth0, объединяющий множество функций, и он работает хорошо, но, как и все эти вещи, его потребности есть немного работы и немного разочарований.
Марк Редман
Когда у меня одна аутентификация работает хорошо, я опубликую подробный ответ на нее. Я только что работал над аутентификацией на прошлой неделе. И нет ничего
johnny 5
0

Социальный вход в систему несложно реализовать с помощью Identity, но требуется некоторая первоначальная настройка, и иногда шаги, которые вы найдете в документации в Интернете, не идентичны, обычно вы можете найти помощь в этом в разделе разработчиков платформы, которую вы пытаетесь настроить. социальные сети для. Идентичность - это замена старой функциональности членства, которая есть в устаревших версиях инфраструктуры .net. Что я обнаружил удивительным, так это то, что крайние варианты использования, такие как передача токена jwt, который у вас уже есть, в веб-api, нигде не рассматриваются в примерах в Интернете даже при множественном числе, я уверен, что вам не нужны ваши собственные полномочия по токену, чтобы сделать это, но я не нашел ни одного примера того, как передавать данные в get или post, которые не связаны с автономным сервером.

webdev8183
источник
возможно, вам нужен
Джей