.NET Core Identity Server 4 身份验证 VS 身份验证
Posted
技术标签:
【中文标题】.NET Core Identity Server 4 身份验证 VS 身份验证【英文标题】:.NET Core Identity Server 4 Authentication VS Identity Authentication 【发布时间】:2017-06-26 14:04:23 【问题描述】:我试图了解在 ASP.NET Core 中进行身份验证的正确方法。我查看了几个资源(其中大部分已过时)。
Simple-Implementation-Of-Microsoft-Identity
Introduction to Authentication with ASP.Core
MSDNs Introduction to Identity
有些人提供替代解决方案,说明使用基于云的解决方案,例如 Azure AD,或使用 IdentityServer4 并托管我自己的令牌服务器。
在旧版本的 .Net 中,一种更简单的身份验证形式是创建自定义原则并在其中存储额外的身份验证用户数据。
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);
我的问题是:
如何进行类似于以前版本 .Net 中的身份验证方式,旧方式是否仍然有效,或者是否有更新版本。
使用自己的令牌服务器与创建自己的自定义原则有何优缺点?
当使用基于云的解决方案或单独的令牌服务器时,您将如何将其与您当前的应用程序集成,我的应用程序中是否仍需要用户表,您将如何将两者关联起来?
既然有这么多不同的解决方案,我该如何创建一个企业应用程序,以允许通过 Gmail/Facebook 登录,同时仍然能够扩展到其他 SSO
这些技术有哪些简单的实现方式?【问题讨论】:
这个问题太宽泛,而且还高度基于意见。可能的答案太多,或者对于这种格式来说,好的答案太长了。请添加详细信息以缩小答案集或隔离可以在几段中回答的问题。许多好的问题会根据专家的经验产生一定程度的意见,但这个问题的答案往往几乎完全基于意见,而不是事实、参考资料或特定的专业知识。 @Nkosi 抱歉这句话是这样的。我澄清了这一点更具体 【参考方案1】:TL;DR
IdentityServer = 通过 OAuth 2.0/OpenId-Connect 的令牌加密和验证服务
ASP.NET 身份 = 当前 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 中的实体:
AspNet 用户 AspNetUserRoles AspNetUserClaims AspNetUserLogins(用于链接外部身份提供商,如 Google、AAD) AspNetUserTokens(用于存储用户积累的 access_tokens 和 refresh_tokens 等内容)使用自己的令牌服务器与创建自己的自定义原则有何优缺点?
令牌服务器将是一个生成包含授权和/或身份验证信息的简单数据结构的系统。授权通常采用名为 access_token 的令牌。这将是“房子的钥匙”,可以这么说,让您通过门口进入受保护资源的住所,通常是 Web 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 协议,因此您也不需要他们的自定义集成包,例如like this one)。此外,ADFS 在 ASP.NET Core Identity 上尚不可用。
请参阅此文档以开始使用 ASP.NET Identity 中的外部提供程序:
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/
既然有这么多不同的解决方案,我该如何创建一个企业应用程序,以允许通过 Gmail/Facebook 登录,同时仍然能够扩展到其他 SSO
如上所述,ASP.NET Identity 已经做到了这一点。创建“外部提供者”表和数据驱动您的外部登录过程相当容易。因此,当出现新的“SSO”时,只需添加一个新行,其中包含提供商的 url、客户端 ID 和他们给你的秘密等属性。 ASP.NET Identity 已经在 Visual Studio 模板中内置了 UI,但请参阅 Social Login 以获得更酷的按钮。
总结
如果您只需要具有密码登录功能的用户表和用户配置文件,那么 ASP.NET Identity 是完美的选择。无需涉及外部当局。但是,如果有许多应用程序需要访问许多 api,那么一个独立的权限来保护和验证身份和访问令牌是有意义的。 IdentityServer 非常适合,或参阅 openiddict-core 或 Auth0 了解云解决方案。
我很抱歉,这没有达到目的,或者它过于介绍性。请随时互动以获得您正在寻找的靶心。
附录:Cookie 身份验证
要使用 cookie 进行基本身份验证,请按以下步骤操作。但是,据我所知,不支持自定义声明主体。要达到相同的效果,请使用 ClaimPrincipal
对象的声明列表。
在 Visual Studio 2015/2017 中创建一个新的 ASP.NET Core 1.1 Web 应用程序,在对话框中选择“无身份验证”。然后添加包:
Microsoft.AspNetCore.Authentication.Cookies
在Startup.cs
的Configure
方法下放置这个(在app.UseMvc
之前):
app.UseCookieAuthentication(new CookieAuthenticationOptions
AuthenticationScheme = "MyCookieMiddlewareInstance",
LoginPath = new PathString("/Controller/Login/"),
AutomaticAuthenticate = true,
AutomaticChallenge = true
);
然后构建一个登录 ui 并将 html 表单发布到一个 Action 方法,如下所示:
[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 对象应该有您的自定义声明,并且可以轻松检索 ClaimPrincipal 的 List 集合。
我希望这就足够了,因为一个完整的解决方案/项目对于 *** 帖子来说似乎有点多。
【讨论】:
请展示在核心中实现身份验证的示例 ASP.NET Core 文档显示了规范示例:docs.microsoft.com/en-us/aspnet/core/security/authentication/…。 如果可以请发布一个简单的身份验证示例。如果没有链接以便人们可以访问资源,我将发布有关如何设置 IdentityServer4 的深入答案 对于 IdentityServer,这是否有您正在寻找的示例:identityserver4.readthedocs.io/en/dev/quickstarts/…? 对于 ASP.NET Identity,这没有示例,还是您所说的内容已过时? docs.microsoft.com/en-us/aspnet/core/security/authentication/…【参考方案2】:TL;DR
我真的很想展示有关如何正确实施 IdentityServer4 的完整帖子,但我尝试将所有文本都放入其中,但这超出了 *** 接受的限制,因此我将改正一些提示和我已经做过的事情学习了。
使用令牌服务器与 ASP 身份有什么好处?
令牌服务器有很多好处,但并不适合所有人。如果您正在实施类似企业的解决方案,您希望多个客户端能够登录,令牌服务器是您最好的选择,但如果您只是制作一个想要支持外部登录的简单网站,您可以摆脱 ASP 身份和一些中间件。
Identity Server 4 技巧
与我见过的许多其他框架相比,Identity server 4 的文档记录得很好,但很难从头开始并看到全貌。
我的第一个错误是尝试使用 OAuth 作为身份验证,是的,有一些方法可以这样做,但 OAuth 用于授权而不是身份验证,如果您想使用 OpenIdConnect (OIDC) 进行身份验证
就我而言,我想创建一个连接到 Web api 的 javascript 客户端。 我查看了很多解决方案,但最初我尝试使用 webapi 调用针对 Identity Server 的 Authenticate 并且只是要让该令牌持久存在,因为它已针对服务器进行了验证。该流程可能可行,但存在很多缺陷。
当我找到 Javascript 客户端示例时,我终于找到了正确的流程。您的客户端登录并设置令牌。然后你的 web api 使用 OIdc 客户端,它将根据 IdentityServer 验证你的访问令牌。
连接到商店和迁移 一开始我对迁移有很多误解。我的印象是运行迁移是在内部从 dll 生成 SQL,而不是使用您配置的 Context 来确定如何创建 SQL。
迁移有两种语法,知道您的计算机使用哪一种很重要:
dotnet ef migrations add InitialIdentityServerMigration -c ApplicationDbContext
Add-Migration InitialIdentityServerDbMigration -c ApplicationDbContext
我认为 Migration 之后的参数是名称,为什么您需要一个名称我不确定,ApplicationDbContext
是您要在其中创建的 Code-First DbContext。
迁移使用一些自动魔法从您的启动配置中找到您的连接字符串,我只是假设它使用了来自服务器资源管理器的连接。
如果您有多个项目,请确保将 ApplicationDbContext 设置为启动项目。
在实现授权和身份验证时有很多变动的部分,希望这篇文章对某人有所帮助。完全理解身份验证的最简单方法是挑选他们的示例,将所有内容拼凑在一起,并确保您阅读了文档
【讨论】:
add-migration 之后的名称是与您所做的发布/更改相关的参考。将使用相同的名称添加迁移脚本 Up &Down。 @Jay 感谢您的澄清 Identity server 的配置 db context 仍然不如 IdentityDbContext。创建自定义实现是一种痛苦。 Identityserver 4 现在似乎不太积极地发布 .core 更新之后的新更新。【参考方案3】:ASP.NET 身份 - 这是一种用于验证您的应用程序(无论是承载身份验证还是基本身份验证)的构建方式,它为我们提供了现成的代码来执行用户注册、登录、更改密码等等。
现在考虑我们有 10 个不同的应用程序,在所有 10 个应用程序中做同样的事情是不可行的。这种非常脆弱和非常糟糕的做法。
为了解决这个问题,我们可以做的是集中我们的身份验证和授权,这样无论何时发生任何更改都不会影响我们所有的 10 个应用程序。
身份服务器为您提供了同样的功能。我们可以创建一个仅用作身份服务的示例 Web 应用程序,它将验证您的用户并提供一些 JWT 访问令牌。
【讨论】:
正是我需要的。【参考方案4】:我一直使用内置的 ASP.NET 身份(和以前的成员身份)授权/身份验证,我最近实现了 Auth0 (https://auth0.com),并推荐将此作为其他尝试。
【讨论】:
Auth0 .net 核心示例实现起来非常快速和简单,但是使用所有功能需要相当多的工作,我已经实现了集成了很多功能的 Auth0,而且效果很好,但是像所有这些东西,它的需要有一点工作和一些挫折。 当我的身份验证运行良好时,我会在上面发布一个深入的答案。上周我一直在进行身份验证。没有什么比它应该的那样严格【参考方案5】:使用 Identity 实现社交登录并不难,但涉及一些初始设置,有时您在文档中在线找到的步骤并不相同,通常您可以在您所在平台的开发人员部分找到相关帮助试图设置社交登录。身份是 .net 框架的旧版本中旧成员资格功能的替代品。我发现令人惊讶的是边缘用例,例如将您已经拥有的 jwt 令牌传递给 web api,在线示例中的任何地方都没有涵盖即使在复数方面,我相信您不需要自己的令牌权限来执行此操作,但我还没有找到一个关于如何在不处理自托管服务器的 get 或 post 中传递数据的示例。
【讨论】:
也许你在关注这个docs.identityserver.io/en/release/quickstarts/…以上是关于.NET Core Identity Server 4 身份验证 VS 身份验证的主要内容,如果未能解决你的问题,请参考以下文章
.Net Core 自定义身份验证使用 API 密钥和 Identity Server 4
JWT 不记名令牌不适用于 ASP.Net Core 3.1 + Identity Server 4
进程内和进程外托管的 ASP .NET Core 3 + Identity Server 问题
如何撤销存储在 Identity Server 数据库中的 asp net core 中的刷新令牌
SignalR 授权无法在带有 Identity Server 的 asp.net core angular SPA 中开箱即用
如何使用 ASP.NET Core 3.1 将 Android 应用程序集成到 Identity Server 以进行身份验证?