.NET Core身份服务器4身份验证VS身份身份验证

.NET Core身份服务器4身份验证VS身份身份验证

问题描述:

我试图了解在ASP.NET Core中进行身份验证的正确方法.我看了几个资源(其中大多数已过时).

I'm trying to understand the proper way to do authentication in ASP.NET Core. I've looked at several Resource (Most of which are out dated).

使用ASP.Core进行身份验证

MSDN身份简介

有人提供替代性解决方案,说明要使用基于云的解决方案(例如Azure AD),或者使用IdentityServer4并托管我自己的令牌服务器.

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.

在.Net的较旧版本中,身份验证的一种较简单形式是创建自定义原则,并在其中存储其他身份验证用户数据.

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.

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,然后将其返回给客户端.

Then you would Serialize your data into a cookie and return it back to the client.

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一样进行身份验证,是否仍然可以使用旧方法或是否有较新版本.

  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.

使用自己的令牌服务器和创建自己的自定义原理的利弊是什么?

What are the pros and cons of using your own token server verses creating your own custom principle?

在使用基于云的解决方案或单独的令牌服务器时,如何将其与当前应用程序集成,我是否仍需要在我的应用程序中使用一张用户表,如何将两者关联?

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?

由于存在众多不同的解决方案,因此我该如何创建企业应用程序,以允许通过Gmail/Facebook登录,同时仍然能够扩展到其他SSO.

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

TL; DR

IdentityServer =通过OAuth 2.0/OpenId-Connect进行令牌加密和验证服务

IdentityServer = token encryption and validation services via OAuth 2.0/OpenId-Connect

ASP.NET身份= ASP.NET中的当前身份管理策略

ASP.NET Identity = current Identity Management strategy in ASP.NET

我如何才能像以前版本的.Net一样进行身份验证,是否仍然可以使用旧方法或是否有较新版本.

我认为没有理由无法在ASP.NET Core中实现旧方法,但是总的来说,该策略已被ASP.NET Identity取代,并且ASP.NET Identity在ASP.NET Core中仍然有效.

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.

https://docs.microsoft.com/zh-我们/aspnet/core/security/authentication/identity

ASP.NET Identity使用SQL Server这样的后备存储来保存用户信息,例如用户名,密码(散列),电子邮件,电话,并可以轻松地扩展以保存FirstName,LastName或其他任何信息.因此,实际上没有理由将用户信息加密为cookie并将其从客户端来回传递到服务器.它支持诸如用户声明,用户令牌,用户角色和外部登录之类的概念.这是ASP.NET 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. So, there really no reason to encrypt user information into a cookie and pass it back and forth from client to server. It supports notions like user claims, user tokens, user roles, and external logins. Here are the entities in ASP.NET Identity:

  • AspNetUsers
  • AspNetUserRoles
  • AspNetUserClaims
  • AspNetUserLogins(用于链接外部身份提供商,例如Google,AAD)
  • AspNetUserTokens(用于存储用户积累的诸如access_tokens和refresh_tokens之类的东西)

使用自己的令牌服务器和创建自己的自定义原理的利弊是什么?

令牌服务器将是一个生成包含授权和/或认证信息的简单数据结构的系统.授权通常使用名为 access_token 的令牌的for.可以这么说,这就是房子的钥匙",它使您可以进入门口,进入通常是网络api的受保护资源的住所.对于身份验证,id_token包含用户/人员的唯一标识符.虽然通常在access_token中放入这样的标识符,但是现在有专用的协议可以这样做: OpenID-Connect .

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. 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. For Authentication, the id_token contains a unique identifier for a user/person. While it is common to put such an identifier in the access_token, there is now a dedicated protocol for doing that: OpenID-Connect.

拥有自己的安全令牌服务(STS)的原因是为了通过加密保护您的信息资产,并控制哪些客户端(应用程序)可以访问这些资源.此外,OpenID-Connect规范中现在存在用于身份控制的标准. IdentityServer是OAuth 2.0授权服务器与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. Furthermore, the standards for identity controls now exist in OpenID-Connect specifications. IdentityServer is an example of a OAuth 2.0 Authorization Server combined with an OpenID-Connect Authentication server.

但是,如果您只想在应用程序中使用用户表,则不需要执行任何操作.您不需要令牌服务器-只需使用ASP.NET身份. ASP.NET Identity将您的用户映射到 ClaimsIdentity 对象-不需要自定义IPrincipal类.

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 Identity maps your User to a ClaimsIdentity object on the server- no need for a custom IPrincipal class.

在使用基于云的解决方案或单独的令牌服务器时,如何将其与当前应用程序集成,我仍将在应用程序中需要一个用户表,如何将两者关联?

请参阅以下教程,以将单独的身份解决方案与应用程序集成: https://identityserver4.readthedocs.io/en/latest/quickstarts/0_overview.html https://auth0.com/docs/quickstart/webapp/aspnet-core

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

您至少需要两列表格,将用户名映射到外部提供商的用户标识符.这就是ASP.NET Identity中AspNetUserLogins表的功能.但是,该表中的行取决于AspNetUsers中的User记录.

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. The rows in that table however are dependent on the being a User record in AspNetUsers.

ASP.NET Identity已支持外部提供商,例如Google,Microsoft,Facebook,任何OpenID-Connect提供商,Azure AD. (Google和Microsoft已经实现了OpenID-Connect协议,因此您也不需要它们的自定义集成包喜欢这样的).此外,ADFS在ASP.NET Core Identity上尚不可用.

ASP.NET Identity supports external providers like Google, Microsoft, Facebook, any OpenID-Connect provider, Azure AD are already there. (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). Also, ADFS is not yet available on ASP.NET Core Identity.

请参阅此文档,以开始使用ASP.NET Identity中的外部提供程序:

See this doc to get started with external providers in ASP.NET Identity:

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

由于存在众多不同的解决方案,我该如何创建企业应用程序,以允许通过Gmail/Facebook登录,同时仍然能够扩展到其他SSO.

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

如上所述,ASP.NET Identity已经做到了这一点.创建外部提供程序"表很容易,数据可以驱动您的外部登录过程.因此,当出现新的"SSO"时,只需添加一个新行,其中包含提供商的url,客户端ID和它们提供给您的秘密之类的属性. ASP.NET Identity已经在其中的Visual Studio模板中内置了UI,但请参见社交登录较凉的按钮.

As explained above, ASP.NET Identity already does this. 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. ASP.NET Identity already has the UI built in there Visual Studio templates, but see Social Login for cooler buttons.

摘要

如果您只需要具有密码登录功能的用户表和用户配置文件,则ASP.NET Identity非常适合.无需外部机构的参与.但是,如果有许多应用程序需要访问许多api,那么保护和验证身份以及访问令牌的独立权限就很有意义. IdentityServer非常适合,请参见 openiddict-core

If you just need a users table with password sign in capabilities and a user profile, then ASP.NET Identity is perfect. 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. IdentityServer is a good fit, or see openiddict-core, or Auth0 for a cloud solution.

我很抱歉,这没有达到目标,或者介绍性太强.请随时进行互动,以吸引您所需要的靶心.

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.

附录:Cookie身份验证

要使用Cookie进行裸身身份验证,请按照以下步骤操作.但是,据我所知,不支持自定义声明主体.为了达到相同的效果,请使用ClaimPrincipal对象的Claims列表.

To do bare bones authentication with cookies, follow these steps. But, to my knowledge a custom claims principal is not supported. To achieve the same effect, utilize the Claims list of the ClaimPrincipal object.

在Visual Studio 2015/2017中创建一个新的ASP.NET Core 1.1 Web应用程序,在对话框中选择无身份验证".然后添加软件包:

Create a new ASP.NET Core 1.1 Web Application in Visual Studio 2015/2017 choosing "No Authentication" in the dialog. Then add package:

Microsoft.AspNetCore.Authentication.Cookies

Startup.cs中的Configure方法下,将其放置(在app.UseMvc之前):

Under the Configure method in Startup.cs place this (before app.UseMvc):

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

然后构建一个登录ui并将html表单发布到这样的Action方法中:

Then build a login ui and post the html Form to an Action Method like this:

[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集合.

The HttpContext.User object should have your custom claims and are easily retrievable the List collection of the ClaimPrincipal.

我希望这足够了,因为对于*帖子来说,完整的解决方案/项目似乎有点多.

I hope this suffices, as a full Solution/Project seems a bit much for a * post.