简体   繁体   English

.NET Core Identity Server 4身份验证VS身份验证

[英].NET Core Identity Server 4 Authentication VS Identity Authentication

I'm trying to understand the proper way to do authentication in ASP.NET Core. 我试图了解在ASP.NET Core中进行身份验证的正确方法。 I've looked at several Resource (Most of which are out dated). 我看过几个资源(其中大部分都已过时)。

Some people provide altenative solutions stating to use a cloud based solution such as Azure AD, or to Use IdentityServer4 and host my own Token Server. 有些人提供了使用基于云的解决方案(如Azure AD)或使用IdentityServer4并托管我自己的令牌服务器的替代解决方案。

In Older version Of .Net one of the simpler forms of authentication would be to create an Custom Iprinciple and store additional authentication user data inside. 在早期版本的.Net中,一种更简单的身份验证形式是创建自定义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; }
}

Then you would Serialize your data into a cookie and return it back to the client. 然后,您将数据序列化为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);
}

My questions are: 我的问题是:

  1. How can I authenticate similar to the way done in previous version's of .Net does the old way still work or is there a newer version. 我如何进行身份验证,类似于以前版本的.Net中的方式,旧的方式仍然有效或是否有更新的版本。

  2. What are the pros and cons of using your own token server verses creating your own custom principle? 使用自己的令牌服务器与创建自己的自定义原则有什么优缺点?

  3. When using a cloud based solution or a separate Token server how would you Integrate that with your current application, would I would still need a users table in my application how would you associate the two? 当使用基于云的解决方案或单独的令牌服务器时,如何将其与当前应用程序集成,我是否仍然需要在我的应用程序中使用用户表如何关联这两者?

  4. Being that there are so many different solutions how can I create an enterprise application, to allow Login through Gmail/Facebook while still being able to expand to other SSO's 由于有这么多不同的解决方案,我如何创建企业应用程序,允许通过Gmail / Facebook登录,同时仍然可以扩展到其他SSO的

  5. What are some simple implementations of these technologies? 这些技术的一些简单实现是什么?

TL;DR TL; DR

IdentityServer = token encryption and validation services via OAuth 2.0/OpenId-Connect IdentityServer =通过OAuth 2.0 / OpenId-Connect进行令牌加密和验证服务

ASP.NET Identity = current Identity Management strategy in ASP.NET ASP.NET Identity = ASP.NET中的当前身份管理策略

How can I authenticate similar to the way done in previous version's of .Net does the old way still work or is there a newer version. 我如何进行身份验证,类似于以前版本的.Net中的方式,旧的方式仍然有效或是否有更新的版本。

I see no reason why you couldn't achieve the old way in ASP.NET Core, but in general, that strategy was replaced with ASP.NET Identity, and ASP.NET Identity is alive and well in ASP.NET Core. 我认为没有理由不能在ASP.NET Core中实现旧方法,但总的来说,该策略已被ASP.NET身份所取代,并且ASP.NET身份在ASP.NET Core中很有用。

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

ASP.NET Identity uses a backing store like SQL Server to hold user information like username, password (hashed), email, phone and easily be extended to hold FirstName, LastName or whatever else. ASP.NET Identity使用像SQL Server这样的后备存储来保存用户信息,如用户名,密码(哈希),电子邮件,电话,并且可以轻松扩展以保存FirstName,LastName或其他任何内容。 So, there really no reason to encrypt user information into a cookie and pass it back and forth from client to server. 因此,没有理由将用户信息加密到cookie中并在客户端之间来回传递。 It supports notions like user claims, user tokens, user roles, and external logins. 它支持用户声明,用户令牌,用户角色和外部登录等概念。 Here are the entities in ASP.NET Identity: 以下是ASP.NET标识中的实体:

  • AspNetUsers AspNetUsers
  • AspNetUserRoles AspNetUserRoles
  • AspNetUserClaims AspNetUserClaims
  • AspNetUserLogins (for linking external identity providers, like Google, AAD) AspNetUserLogins(用于链接外部身份提供商,如Google,AAD)
  • AspNetUserTokens (for storing things like access_tokens and refresh_tokens amassed by the user) AspNetUserTokens(用于存储用户积累的access_tokens和refresh_tokens之类的东西)

What are the pros and cons of using your own token server verses creating your own custom principle? 使用自己的令牌服务器与创建自己的自定义原则有什么优缺点?

A token server would be a system that generates a simple data structure containing Authorization and/or Authentication information. 令牌服务器将是生成包含授权和/或认证信息的简单数据结构的系统。 Authorization usually takes the for of a token named access_token . 授权通常使用名为access_token的令牌。 This would be the "keys to the house", so to speak, letting you through the doorway and into the residence of a protected resource, usually a web api. 这将是“房子的钥匙”,可以说,让你穿过门口进入受保护资源的住所,通常是网络api。 For Authentication, the id_token contains a unique identifier for a user/person. 对于身份验证, id_token包含用户/个人的唯一标识符。 While it is common to put such an identifier in the access_token, there is now a dedicated protocol for doing that: OpenID-Connect . 虽然在access_token中放置这样的标识符很常见,但现在有一个专用协议: OpenID-Connect

The reason to have your own Security Token Service (STS), would to be to safeguard your information assets, via cryptography, and control which clients (applications) can access those resources. 拥有自己的安全令牌服务(STS)的原因是通过加密技术保护您的信息资产,并控制哪些客户端(应用程序)可以访问这些资源。 Furthermore, the standards for identity controls now exist in OpenID-Connect specifications. 此外,身份控制标准现在存在于OpenID-Connect规范中。 IdentityServer is an example of a OAuth 2.0 Authorization Server combined with an OpenID-Connect Authentication server. IdentityServer是OAuth 2.0授权服务器与OpenID-Connect身份验证服务器相结合的示例。

But none of this is necessary if you just want a user table in your application. 但是,如果您只想在应用程序中使用用户表,则无论如何都不需要这样做。 You don't need a token server- just use ASP.NET Identity. 您不需要令牌服务器 - 只需使用ASP.NET标识。 ASP.NET Identity maps your User to a ClaimsIdentity object on the server- no need for a custom IPrincipal class. ASP.NET Identity将您的用户映射到服务器上的ClaimsIdentity对象 - 无需自定义IPrincipal类。

When using a cloud based solution or a separate Token server how would you Integrate that with your current application, would I would still need a users table in my application how would you associate the two? 当使用基于云的解决方案或单独的令牌服务器时,如何将其与当前应用程序集成,我是否仍然需要在我的应用程序中使用用户表如何关联这两者?

See these tutorials for integrating separate identity solutions with an application: https://identityserver4.readthedocs.io/en/latest/quickstarts/0_overview.html https://auth0.com/docs/quickstart/webapp/aspnet-core 请参阅这些教程,以便将单独的身份解决方案与应用程序集成: https//identityserver4.readthedocs.io/en/latest/quickstarts/0_overview.html https://auth0.com/docs/quickstart/webapp/aspnet-core

At a minimum you would need a two column table mapping the username to the external provider's user identifier. 您至少需要一个两列表,将用户名映射到外部提供商的用户标识符。 This is what the AspNetUserLogins table does in ASP.NET Identity. 这就是AspNetUserLogins表在ASP.NET Identity中的作用。 The rows in that table however are dependent on the being a User record in AspNetUsers. 但是,该表中的行依赖于AspNetUsers中的用户记录。

ASP.NET Identity supports external providers like Google, Microsoft, Facebook, any OpenID-Connect provider, Azure AD are already there. ASP.NET Identity支持外部提供商,如Google,Microsoft,Facebook,任何OpenID-Connect提供商,Azure AD已经存在。 (Google and Microsoft have already implemented the OpenID-Connect protocol so you don't need their custom integration packages either, like this one , for example). (谷歌和微软已经实施了OpenID-Connect协议,因此你不需要他们的自定义集成包, 例如这个 )。 Also, ADFS is not yet available on ASP.NET Core Identity. 此外,ASP.NET Core Identity上尚未提供ADFS。

See this doc to get started with external providers in ASP.NET Identity: 请参阅此文档以开始使用ASP.NET标识中的外部提供程序:

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

Being that there are so many different solutions how can I create an enterprise application, to allow Login through Gmail/Facebook while still being able to expand to other SSO's 由于有这么多不同的解决方案,我如何创建企业应用程序,允许通过Gmail / Facebook登录,同时仍然可以扩展到其他SSO的

As explained above, ASP.NET Identity already does this. 如上所述,ASP.NET Identity已经这样做了。 It's fairly easy to create an "External Providers" table and data drive your external login process. 创建“外部供应商”表和数据驱动外部登录过程相当容易。 So when a new "SSO" comes along, just add a new row with the properties like the provider's url, the client id and secret they give you. 所以当一个新的“SSO”出现时,只需添加一个新行,其中包含提供者的URL,客户端ID和他们给你的秘密等属性。 ASP.NET Identity already has the UI built in there Visual Studio templates, but see Social Login for cooler buttons. ASP.NET Identity已经在Visual Studio模板中内置了UI,但是请参阅社交登录以获取更酷的按钮。

Summary 摘要

If you just need a users table with password sign in capabilities and a user profile, then ASP.NET Identity is perfect. 如果您只需要具有密码登录功能和用户配置文件的用户表,那么ASP.NET身份就是完美的。 No need to involve external authorities. 无需涉及外部机构。 But, if have many applications needing to access many apis, then an independent authority to secure and validate identity and access tokens makes sense. 但是,如果有许多应用程序需要访问许多api,那么保护和验证身份和访问令牌的独立权限是有道理的。 IdentityServer is a good fit, or see openiddict-core , or Auth0 for a cloud solution. IdentityServer非常适合,或者参见openiddict-coreAuth0以获得云解决方案。

My apologies is this isn't hitting the mark or if it is too introductory. 我的道歉是,这不符合标记,或者它是否过于介绍。 Please feel free to interact to get to the bulls-eye you are looking for. 请随意互动,以获得您正在寻找的靶心。

Addendum: Cookie Authentication 附录:Cookie身份验证

To do bare bones authentication with cookies, follow these steps. 要使用cookie进行裸骨身份验证,请按照下列步骤操作。 But, to my knowledge a custom claims principal is not supported. 但是,据我所知,不支持自定义声明主体。 To achieve the same effect, utilize the Claims list of the ClaimPrincipal object. 要获得相同的效果,请使用ClaimPrincipal对象的Claims列表。

Create a new ASP.NET Core 1.1 Web Application in Visual Studio 2015/2017 choosing "No Authentication" in the dialog. 在Visual Studio 2015中创建一个新的ASP.NET Core 1.1 Web应用程序,在对话框中选择“无身份验证”。 Then add package: 然后添加包:

Microsoft.AspNetCore.Authentication.Cookies

Under the Configure method in Startup.cs place this (before app.UseMvc ): Startup.csConfigure方法下放置(在app.UseMvc之前):

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

Then build a login ui and post the html Form to an Action Method like this: 然后构建一个登录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();
}

The HttpContext.User object should have your custom claims and are easily retrievable the List collection of the ClaimPrincipal. HttpContext.User对象应具有您的自定义声明,并且可以轻松检索ClaimPrincipal的List集合。

I hope this suffices, as a full Solution/Project seems a bit much for a StackOverflow post. 我希望这足够了,因为完整的解决方案/项目对于StackOverflow帖子来说似乎有点多了。

TL;DR TL; DR

I would really like to Show A Full posting on how to properly implement IdentityServer4 but I tried to fit All of the Text in but it was beyond the limit of what StackOverflow Accepts so instead I will right some tips and things I've learned. 我真的想要展示如何正确实现IdentityServer4的完整帖子,但我尝试适应所有文本,但它超出了StackOverflow接受的限制,所以我会找到一些我学到的技巧和事情。

What are the Benefits of using a Token Server Vs ASP Identity? 使用令牌服务器与ASP身份有什么好处?

A token server, has a lot of benefit's but it isn't right for everyone. 令牌服务器有很多好处,但并不适合所有人。 If you are implementing an enterprise like solution, where you want multiple client to be able to login, Token server is your best bet, but if you just making a simple website that want to support External Logins, You can get Away With ASP Identity and some Middleware. 如果您正在实施类似解决方案的企业,您希望多个客户端能够登录,那么Token服务器是您最好的选择,但如果您只是建立一个想要支持外部登录的简单网站,您可以获得远离ASP身份和一些中间件。

Identity Server 4 Tips Identity Server 4提示

Identity server 4 is pretty well documented compared to a lot of other frameworks I've seen but it's hard to start from scratch and see the whole picture. 与我见过的很多其他框架相比,身份服务器4已经有了很好的文档记录,但很难从头开始看到整体情况。

My first mistak was trying to use OAuth as authentication, Yes, there are ways to do so but OAuth is for Authorization not authentication, if you want to Authenticate use OpenIdConnect (OIDC) 我的第一个错误是尝试使用OAuth作为身份验证,是的,有很多方法可以这样做但OAuth用于授权而不是身份验证,如果要进行身份验证使用OpenIdConnect(OIDC)

In my case I wanted to create A javascript client, who connects to a web api. 在我的情况下,我想创建一个连接到web api的javascript客户端。 I looked at a lot of the solutions, but initially I tried to use the the webapi to call the Authenticate against Identity Server and was just going to have that token persist because it was verified against the server. 我查看了很多解决方案,但最初我尝试使用webapi来针对Identity Server调用Authenticate,并且只是因为它是针对服务器进行验证而持续存在该令牌。 That flow potentially can work but It has a lot of flaws. 这种流程可能会起作用,但它有很多缺陷。

Finally the proper flow when I found the Javascript Client sample I got the right flow. 最后,当我找到Javascript客户端示例时,正确的流程得到了正确的流程。 You Client logs in, and sets a token. 您的客户端登录并设置令牌。 Then you have your web api consume the OIdc Client, which will verify you're access token against IdentityServer. 然后你的web api使用OIdc Client,它将验证你是否是IdentityServer的访问令牌。

Connecting to Stores and Migrations I had a lot of a few misconceptions with migrations at first. 连接到商店和迁移我最初对迁移有很多误解。 I was under the impression that running a migration Generated the SQL from the dll internally, instead of using you're configured Context to figure out how to create the SQL. 我的印象是运行迁移在内部从dll生成SQL,而不是使用您配置的Context来弄清楚如何创建SQL。

There are two syntaxes for Migrations knowing which one your computer uses is important: 迁移有两种语法,知道您的计算机使用哪一种很重要:

dotnet ef migrations add InitialIdentityServerMigration -c ApplicationDbContext

Add-Migration InitialIdentityServerDbMigration -c ApplicationDbContext

I think the parameter after the Migration is the name, why you need a name I'm not sure, the ApplicationDbContext is a Code-First DbContext in which you want to create. 我认为Migration之后的参数是名称,为什么你需要一个我不确定的名字, ApplicationDbContext是你想要创建的Code-First DbContext。

Migrations use some auto-magic to find you're Connection string from how your start up is configured, I just assumed it used a connection from the Server Explorer. 迁移使用一些自动魔法来查找启动配置的连接字符串,我只是假设它使用了服务器资源管理器中的连接。

If you have multiple projects make sure you have the project with the ApplicationDbContext set as your start up. 如果您有多个项目,请确保将具有ApplicationDbContext的项目设置为启动项目。

There is a lot of moving parts when Implementing Authorization and Authentication, Hopefully, this post helps someone. 实现授权和身份验证时有很多可移动的部分,希望这篇文章可以帮助某些人。 The easiest way to full understand authentications is to pick apart their examples to piece everything together and make sure your read the documentation 完全理解身份验证的最简单方法是分开他们的示例,将所有内容拼凑在一起,并确保您阅读文档

我一直使用内置的ASP.NET身份(以及之前的成员身份)授权/身份验证,我最近已经实现了Auth0( https://auth0.com )并建议将其作为其他尝试。

Social logins are not hard to implement with Identity, but there is some initial setup involved and sometimes the steps you find online in the docs are not identical, usually you can find help for that under the developers section of the platform you are trying to setup the social logins for. 使用Identity不难实现社交登录,但是有一些初始设置涉及,有时您在文档中在线找到的步骤并不相同,通常您可以在您尝试设置的平台的开发人员部分找到帮助社交登录。 Identity is the replacement of the old membership functionality found in legacy versions of the .net framework.What I have found surprising is that edge use cases, like passing a jwt token you already have to a web api are not covered anywhere in the examples online even on pluralsight, I am sure you don't need your own token authority to do this but I have not found a single example on how to pass data in a get or post that isn't dealing with a self-hosted server. 身份是替代.net框架的旧版本中的旧成员资格功能。我发现令人惊讶的是,边缘用例,例如将已经拥有的jwt令牌传递给web api,并不在网上示例中的任何地方即使在复数,我相信你不需要你自己的令牌权限来做这个,但我没有找到一个关于如何在不处理自托管服务器的get或post中传递数据的例子。

ASP.NET Identity - this is the build in a way to authenticate your application whether it is Bearer or Basic Authentication, It gives us the readymade code to perform User registration, login, change the password and all. ASP.NET标识 - 这是一种对应用程序进行身份验证的构建方式,无论是承载还是基本身份验证,它为我们提供了现成的代码来执行用户注册,登录,更改密码等等。

Now consider we have 10 different applications and it is not feasible to do the same thing in all 10 apps. 现在考虑我们有10个不同的应用程序,并且在所有10个应用程序中执行相同的操作是不可行的。 that very fragile and very bad practice. 那种非常脆弱和非常糟糕的做法。

to resolve this issue what we can able to do is centralize our Authentication and authorization so whenever any change with this will not affect all our 10 apps. 要解决此问题,我们可以做的是集中我们的身份验证和授权,以便每当有任何更改都不会影响我们的所有10个应用程序。

The identity server provides you the capability to do the same. 身份服务器为您提供了执行相同操作的功能。 we can create one sample web app which just used as Identity service and it will validate your user and provide s some JWT access token. 我们可以创建一个仅用作身份服务的示例Web应用程序,它将验证您的用户并提供一些JWT访问令牌。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM