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

有些人提供替代解决方案,声明使用基于云的解决方案,如Azure AD,或使用IdentityServer 4并托管我自己的令牌服务器.

在旧版本的.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; }
}

然后将数据序列化为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. 当使用基于云的解决方案或单独的令牌服务器时,您将如何将其与您当前的应用程序集成,我的应用程序中是否仍然需要一个USERS表?您如何将两者关联起来?

  4. 既然有这么多不同的解决方案,我如何才能创建一个企业应用程序,允许通过Gmail/Facebook登录,同时仍然能够扩展到其他SSO

  5. 这些技术的一些简单实现是什么?

推荐答案

TL;DR

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

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.

我看不出你为什么不能在ASP中实现旧方法.NET核心,但总的来说,该策略已被ASP取代.NET身份和ASP.NET身份在ASP中非常活跃.净核心.

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

ASP.NET Identity使用SQL Server之类的备份存储来保存用户名、密码(散列)、邮箱、电话等用户信息,并且可以轻松扩展以保存FirstName、LastName或其他任何信息.所以,真的没有理由将用户信息加密到cookie中,并在客户端和服务器之间来回传递.它支持用户声明、用户令牌、用户角色和外部登录等概念.以下是ASP中的实体.网络身份:

  • AspNetUsers
  • AspNetUserRoles
  • AspNetUserClaimes
  • AspNetUserLogins(用于链接外部身份Provider ,如谷歌、AAD)
  • AspNetUserTokens(用于存储用户积累的access_令牌和refresh_令牌等内容)

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

令牌服务器将是生成包含授权和/或认证信息的简单数据 struct 的系统.授权通常采用名为access_token的令牌.可以说,这将是"房子的 keys ",让您通过门口进入受保护资源(通常是Web API)的住所.对于身份验证,id_token包含用户/个人的唯一标识符.虽然在Access_Token中放置这样的标识符是很常见的,但是现在有一个专用的协议来实现这一点:OpenID-Connect.

拥有自己的安全令牌服务(STS)的原因是通过加密保护您的信息assets资源 ,并控制哪些客户端(应用程序)可以访问这些资源.此外,身份控制标准现在存在于OpenID Connect规范中.IdentityServer是OAuth 2.0授权服务器与OpenID Connect身份验证服务器组合的一个示例.

但是,如果您只需要在应用程序中包含一个用户表,则不需要执行这些操作.您不需要令牌服务器-只需使用ASP.NET标识即可.ASP.NET标识将您的用户映射到服务器上的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?

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

您至少需要一个将用户名映射到外部提供者的用户标识符的两列表.这就是AspNetUserLogins表在ASP.NET标识中的作用.但是,该表中的行取决于是否为AspNetUsers中的用户记录.

ASP.NET Identity支持谷歌、微软、Facebook、任何OpenID连接Provider 、Azure广告等外部Provider .(谷歌和微软已经实现了OpenID连接协议,所以你也不需要他们的定制集成包,比如like this one).此外,ASP上还没有ADFS.网络核心身份.

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

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

如上所述,ASP.NET Identity已经做到了这一点.创建"外部提供者"表和数据驱动外部登录过程相当容易.因此,当出现一个新的"SSO"时,只需添加一个新行,其中包含提供者的url、客户端id和它们提供给您的机密等属性.ASP.NET Identity已经在那里内置了Visual Studio模板的UI,但有关更酷的按钮,请参见Social Login.

Summary

如果您只需要一个具有密码登录功能和用户配置文件的用户表,那么ASP.网络身份是完美的.不需要外部机构参与.但是,如果有许多应用程序需要访问许多API,那么一个独立的机构来保护和验证身份和访问令牌是有意义的.IdentityServer非常适合,云解决方案请参见openiddict-coreAuth0.

我很抱歉,这没有切中要害,或者太具介绍性了.请随意互动,到达您正在寻找的靶心.

Addendum: Cookie Authentication

要使用cookie进行基本身份验证,请执行以下步骤.但是,据我所知,不支持自定义索赔主体.为了达到同样的效果,请使用ClaimPrincipal个对象的索赔 list .

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

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表单发布到如下操作方法:

[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.用户对象应该有您的自定义声明,并且可以很容易地从ClainPrincipal的列表集合中检索.

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

Asp.net相关问答推荐

在 Web.Config 的 Location Path 元素中指定多个目录

如何向 Array.IndexOf 添加不区分大小写的选项

指定的 CGI 应用程序遇到错误,服务器终止了进程

ASP.NET @Register 与 @Reference

在每页级别增加 ASP.Net 超时

无法访问,内部,资源文件?

ASP.NET IIS - 请求何时排队?

新的 ASP.NET MVC 5 应用程序如何知道如何创建数据库以及帐户控制器如何访问数据库?

HttpContext.Current.Cache.Insert 和 HttpContext.Current.Cache.Add 有什么区别

asp.net Button OnClick 事件未触发

如何从 HTTP 请求中获取 MAC 地址?

在 ASP.NET MVC 中使用 Razor 创建可重用的 HTML 视图组件

ASP.NET 中的全局资源与本地资源

从 IFrame 重定向父页面

带有 2 个提交按钮/操作的 ASP.Net MVC 4 表单

HttpResponse.End 或 HttpResponse.Close 与 HttpResponse.SuppressContent

SignalR /signalr/hubs 404 未找到

调查 Web.Config 重复部分原因的步骤

ASP.NET 应用程序状态与静态对象

Docker 中的 ASPNETCORE_ENVIRONMENT