.NET Core Identity Server 4 Authentication VS Identity Authentication


92

Tôi đang cố gắng hiểu cách thích hợp để thực hiện xác thực trong ASP.NET Core. Tôi đã xem xét một số Tài nguyên (Hầu hết trong số đó đã cũ).

Một số người cung cấp các giải pháp thay thế nói rằng sử dụng giải pháp dựa trên đám mây như Azure AD hoặc Sử dụng IdentityServer4 và lưu trữ Máy chủ mã thông báo của riêng tôi.

Trong phiên bản cũ hơn của .Net, một trong những hình thức xác thực đơn giản hơn sẽ là tạo Nguyên tắc tùy chỉnh và lưu trữ dữ liệu người dùng xác thực bổ sung bên trong.

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; }
}

Sau đó, bạn sẽ Tuần tự hóa dữ liệu của mình thành một cookie và trả lại cho khách hàng.

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);
}

Câu hỏi của tôi là:

  1. Làm cách nào tôi có thể xác thực tương tự như cách thực hiện trong phiên bản trước của .Net, cách cũ vẫn hoạt động hay có phiên bản mới hơn.

  2. Ưu và nhược điểm của việc sử dụng các câu máy chủ mã thông báo của riêng bạn để tạo ra nguyên tắc tùy chỉnh của riêng bạn là gì?

  3. Khi sử dụng giải pháp dựa trên đám mây hoặc một máy chủ Mã thông báo riêng biệt, bạn sẽ Tích hợp nó với ứng dụng hiện tại của mình như thế nào, tôi vẫn cần một bảng người dùng trong ứng dụng của mình, bạn sẽ kết hợp cả hai như thế nào?

  4. Do có rất nhiều giải pháp khác nhau, làm cách nào để tôi có thể tạo một ứng dụng doanh nghiệp, để cho phép Đăng nhập qua Gmail / Facebook trong khi vẫn có thể mở rộng sang các SSO khác

  5. Một số triển khai đơn giản của những công nghệ này là gì?

Câu hỏi này quá rộng và cũng dựa trên quan điểm cao. Có thể có quá nhiều câu trả lời hoặc câu trả lời tốt sẽ quá dài đối với định dạng này. Vui lòng thêm chi tiết để thu hẹp nhóm câu trả lời hoặc để tách một vấn đề có thể được trả lời trong một vài đoạn văn. Nhiều câu hỏi hay tạo ra một số ý kiến ​​dựa trên kinh nghiệm của chuyên gia, nhưng câu trả lời cho câu hỏi này sẽ có xu hướng gần như hoàn toàn dựa trên ý kiến, thay vì sự kiện, tài liệu tham khảo hoặc chuyên môn cụ thể.
Nkosi

@Nkosi xin lỗi cụm từ theo cách đó. Tôi đã làm rõ điều này để cụ thể hơn
johnny 5

Câu trả lời:


145

TL; DR

IdentityServer = dịch vụ mã hóa và xác thực mã thông báo qua OAuth 2.0 / OpenId-Connect

ASP.NET Identity = chiến lược quản lý danh tính hiện tại trong ASP.NET

Làm cách nào tôi có thể xác thực tương tự như cách thực hiện trong phiên bản trước của .Net, cách cũ vẫn hoạt động hay có phiên bản mới hơn.

Tôi không hiểu lý do gì khiến bạn không thể đạt được cách cũ trong ASP.NET Core, nhưng nói chung, chiến lược đó đã được thay thế bằng ASP.NET Identity và ASP.NET Identity vẫn tồn tại và tốt trong ASP.NET Core.

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

ASP.NET Identity sử dụng một kho dự phòng như SQL Server để lưu giữ thông tin người dùng như tên người dùng, mật khẩu (băm), email, điện thoại và dễ dàng được mở rộng để lưu trữ FirstName, LastName hoặc bất kỳ thứ gì khác. Vì vậy, thực sự không có lý do gì để mã hóa thông tin người dùng thành một cookie và chuyển nó qua lại từ máy khách đến máy chủ. Nó hỗ trợ các khái niệm như xác nhận quyền sở hữu của người dùng, mã thông báo người dùng, vai trò người dùng và thông tin đăng nhập bên ngoài. Đây là các thực thể trong ASP.NET Identity:

  • AspNetUsers
  • AspNetUserRoles
  • AspNetUserClaims
  • AspNetUserLogins (để liên kết các nhà cung cấp danh tính bên ngoài, như Google, AAD)
  • AspNetUserTokens (để lưu trữ những thứ như access_tokens và refresh_tokens do người dùng tích lũy)

Ưu và nhược điểm của việc sử dụng các câu máy chủ mã thông báo của riêng bạn để tạo ra nguyên tắc tùy chỉnh của riêng bạn là gì?

Máy chủ mã thông báo sẽ là một hệ thống tạo ra một cấu trúc dữ liệu đơn giản chứa thông tin Ủy quyền và / hoặc Xác thực. Việc cấp phép thường lấy mã thông báo có tên access_token . Nói cách khác, đây sẽ là "chìa khóa vào nhà", cho phép bạn đi qua ngưỡng cửa và vào nơi cư trú của một tài nguyên được bảo vệ, thường là một ứng dụng web. Đối với Xác thực, id_tokenchứa một số nhận dạng duy nhất cho người dùng / người. Mặc dù người ta thường đặt một mã định danh như vậy trong access_token, nhưng giờ đây có một giao thức chuyên dụng để làm điều đó: OpenID-Connect .

Lý do để có Dịch vụ Mã thông báo Bảo mật (STS) của riêng bạn, sẽ là để bảo vệ tài sản thông tin của bạn, thông qua mật mã và kiểm soát những máy khách (ứng dụng) nào có thể truy cập các tài nguyên đó. Hơn nữa, các tiêu chuẩn về kiểm soát danh tính hiện đã tồn tại trong các thông số kỹ thuật của OpenID-Connect. IdentityServer là một ví dụ về Máy chủ ủy quyền OAuth 2.0 kết hợp với máy chủ Xác thực OpenID-Connect.

Nhưng điều này không cần thiết nếu bạn chỉ muốn có một bảng người dùng trong ứng dụng của mình. Bạn không cần máy chủ mã thông báo - chỉ cần sử dụng ASP.NET Identity. ASP.NET Identity ánh xạ Người dùng của bạn tới một đối tượng ClaimsIdentity trên máy chủ - không cần lớp IPrincipal tùy chỉnh.

Khi sử dụng giải pháp dựa trên đám mây hoặc một máy chủ Mã thông báo riêng biệt, bạn sẽ Tích hợp nó với ứng dụng hiện tại của mình như thế nào, tôi vẫn cần một bảng người dùng trong ứng dụng của mình, bạn sẽ kết hợp cả hai như thế nào?

Xem các hướng dẫn này để tích hợp các giải pháp nhận dạng riêng biệt với một ứng dụng: https://identityserver4.readthedocs.io/en/latest/quickstarts/0_overview.html https://auth0.com/docs/quickstart/webapp/aspnet-core

Tối thiểu bạn sẽ cần một bảng hai cột ánh xạ tên người dùng với mã định danh người dùng của nhà cung cấp bên ngoài. Đây là những gì bảng AspNetUserLogins thực hiện trong ASP.NET Identity. Tuy nhiên, các hàng trong bảng đó phụ thuộc vào bản ghi Người dùng trong AspNetUsers.

ASP.NET Identity hỗ trợ các nhà cung cấp bên ngoài như Google, Microsoft, Facebook, bất kỳ nhà cung cấp OpenID-Connect nào, Azure AD đều đã có ở đó. (Google và Microsoft đã triển khai giao thức OpenID-Connect nên bạn cũng không cần các gói tích hợp tùy chỉnh của họ, chẳng hạn như gói này ). Ngoài ra, ADFS vẫn chưa khả dụng trên ASP.NET Core Identity.

Xem tài liệu này để bắt đầu với các nhà cung cấp bên ngoài trong ASP.NET Identity:

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

Do có rất nhiều giải pháp khác nhau, làm cách nào để tôi có thể tạo một ứng dụng doanh nghiệp, để cho phép Đăng nhập qua Gmail / Facebook trong khi vẫn có thể mở rộng sang các SSO khác

Như đã giải thích ở trên, ASP.NET Identity đã thực hiện điều này. Khá dễ dàng để tạo bảng "Nhà cung cấp bên ngoài" và dữ liệu thúc đẩy quá trình đăng nhập bên ngoài của bạn. Vì vậy, khi một "SSO" mới xuất hiện, chỉ cần thêm một hàng mới với các thuộc tính như url của nhà cung cấp, id khách hàng và bí mật mà họ cung cấp cho bạn. ASP.NET Identity đã có giao diện người dùng được tích hợp sẵn trong các mẫu Visual Studio, nhưng hãy xem Đăng nhập xã hội để biết các nút hay hơn.

Tóm lược

Nếu bạn chỉ cần một bảng người dùng với khả năng đăng nhập bằng mật khẩu và một hồ sơ người dùng, thì ASP.NET Identity là hoàn hảo. Không cần liên quan đến các cơ quan chức năng bên ngoài. Tuy nhiên, nếu có nhiều ứng dụng cần truy cập nhiều apis, thì một cơ quan độc lập để bảo mật và xác thực danh tính và mã thông báo truy cập sẽ có ý nghĩa. IdentityServer rất phù hợp, hoặc xem openiddict-core hoặc Auth0 để biết giải pháp đám mây.

Lời xin lỗi của tôi là điều này không đạt hiệu quả hoặc nếu nó quá giới thiệu. Vui lòng tương tác để đạt được mắt bò mà bạn đang tìm kiếm.

Phụ lục: Xác thực cookie

Để thực hiện xác thực bằng cookie, hãy làm theo các bước sau. Tuy nhiên, theo hiểu biết của tôi, hiệu trưởng yêu cầu tùy chỉnh không được hỗ trợ. Để đạt được hiệu quả tương tự, hãy sử dụng danh sách Yêu cầu của ClaimPrincipalđối tượng.

Tạo Ứng dụng Web ASP.NET Core 1.1 mới trong Visual Studio 2015/2017 bằng cách chọn "Không xác thực" trong hộp thoại. Sau đó thêm gói:

Microsoft.AspNetCore.Authentication.Cookies

Theo Configurephương pháp tại Startup.cschỗ này (trước app.UseMvc):

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

Sau đó, xây dựng một ui đăng nhập và đăng Biểu mẫu html lên một Phương thức hành động như sau:

[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();
}

Đối tượng HttpContext.User phải có các xác nhận quyền sở hữu tùy chỉnh của bạn và có thể dễ dàng truy xuất bộ sưu tập Danh sách của ClaimPrincipal.

Tôi hy vọng điều này là đủ, vì một Giải pháp / Dự án đầy đủ có vẻ hơi nhiều cho một bài đăng trên StackOverflow.


1
Vui lòng hiển thị một ví dụ về việc triển khai xác thực trong lõi
johnny 5

2
Tài liệu ASP.NET Core hiển thị ví dụ chuẩn: docs.microsoft.com/en-us/aspnet/core/security/authentication/… .
travis.js 27/02/17

Nếu bạn có thể, vui lòng đăng một ví dụ đơn giản về xác thực. Không có liên kết để mọi người có tài nguyên để truy cập, tôi sẽ đăng câu trả lời chuyên sâu về cách thiết lập IdentityServer4
johnny 5

Đối với IdentityServer, điều này có ví dụ bạn đang tìm kiếm: identityserver4.readthedocs.io/en/dev/quickstarts/... ?
travis.js

Đối với ASP.NET Identity, điều này không có ví dụ, hay những gì bạn đang nói đã lỗi thời? docs.microsoft.com/en-us/aspnet/core/security/authentication/…
travis.js Ngày

11

TL; DR

Tôi thực sự muốn Hiển thị một bài đăng đầy đủ về cách triển khai IdentityServer4 đúng cách nhưng tôi đã cố gắng đưa Tất cả Văn bản vào nhưng nó đã vượt quá giới hạn của những gì StackOverflow chấp nhận vì vậy thay vào đó tôi sẽ sửa một số mẹo và những điều tôi đã học được.

Lợi ích của việc sử dụng Máy chủ mã thông báo Vs ASP Identity là gì?

Máy chủ mã thông báo, có rất nhiều lợi ích nhưng nó không phù hợp với tất cả mọi người. Nếu bạn đang triển khai một giải pháp tương tự như doanh nghiệp, nơi bạn muốn nhiều khách hàng có thể đăng nhập, máy chủ Mã thông báo là lựa chọn tốt nhất của bạn, nhưng nếu bạn chỉ tạo một trang web đơn giản muốn hỗ trợ Đăng nhập bên ngoài, bạn có thể sử dụng Nhận dạng ASP và một số phần mềm trung gian.

Mẹo Máy chủ Identity 4

Identity server 4 được ghi lại khá tốt so với rất nhiều framework khác mà tôi đã thấy nhưng thật khó để bắt đầu từ đầu và xem toàn cảnh.

Sai lầm đầu tiên của tôi là cố gắng sử dụng OAuth làm xác thực, Có, có nhiều cách để làm như vậy nhưng OAuth dành cho Ủy quyền chứ không phải xác thực, nếu bạn muốn Xác thực, hãy sử dụng OpenIdConnect (OIDC)

Trong trường hợp của tôi, tôi muốn tạo một ứng dụng khách javascript, ứng dụng này kết nối với một api web. Tôi đã xem xét rất nhiều giải pháp, nhưng ban đầu tôi đã cố gắng sử dụng webapi để gọi Xác thực chống lại Máy chủ nhận dạng và sẽ chỉ giữ lại mã thông báo đó vì nó đã được xác minh dựa trên máy chủ. Dòng chảy đó có thể hoạt động nhưng nó có rất nhiều sai sót.

Cuối cùng là quy trình phù hợp khi tôi tìm thấy mẫu Ứng dụng khách Javascript, tôi đã chọn đúng luồng. Khách hàng của bạn đăng nhập và đặt mã thông báo. Sau đó, bạn có api web của mình sử dụng Ứng dụng khách OIdc, ứng dụng này sẽ xác minh bạn đang truy cập mã thông báo chống lại IdentityServer.

Kết nối với Stores và Migrations, tôi đã có rất nhiều quan niệm sai lầm về việc di chuyển lúc đầu. Tôi có ấn tượng rằng việc chạy di chuyển Đã tạo SQL từ dll trong nội bộ, thay vì sử dụng bạn đã định cấu hình Ngữ cảnh để tìm ra cách tạo SQL.

Có hai cú pháp cho Migrations biết máy tính của bạn sử dụng cú pháp nào là quan trọng:

dotnet ef migrations add InitialIdentityServerMigration -c ApplicationDbContext

Add-Migration InitialIdentityServerDbMigration -c ApplicationDbContext

Tôi nghĩ rằng tham số sau Migration là tên, tại sao bạn cần một cái tên, tôi không chắc, đó ApplicationDbContextlà Code-First DbContext mà bạn muốn tạo.

Việc di chuyển sử dụng một số phép thuật tự động để tìm ra bạn Chuỗi kết nối từ cách cấu hình khởi động của bạn, tôi chỉ giả sử nó sử dụng kết nối từ Server Explorer.

Nếu bạn có nhiều dự án, hãy đảm bảo rằng bạn có dự án với ApplicationDbContext được đặt làm phần khởi động của bạn.

Có rất nhiều phần chuyển động khi Thực hiện Ủy quyền và Xác thực, Hy vọng rằng bài đăng này sẽ giúp ích cho ai đó. Cách dễ nhất để hiểu đầy đủ các xác thực là chọn các ví dụ của chúng để ghép mọi thứ lại với nhau và đảm bảo bạn đã đọc tài liệu


tên sau khi bổ sung di chuyển là tham chiếu liên quan đến bản phát hành của bạn / những thay đổi bạn đã thực hiện. cùng tên sẽ được sử dụng để thêm tập lệnh di chuyển Lên & Xuống.
Jay

@Jay Cảm ơn bạn đã làm rõ điều đó
johnny 5

Cấu hình db ngữ cảnh của máy chủ Identity vẫn không tốt bằng IdentityDbContext. tạo triển khai tùy chỉnh là một khó khăn. Identityserver 4 hiện dường như không hoạt động nhiều để phát hành các bản cập nhật mới sau các bản cập nhật .core.
Jay

3

ASP.NET Identity - đây là bản xây dựng theo cách để xác thực ứng dụng của bạn cho dù đó là Bearer hay Basic Authentication, Nó cung cấp cho chúng tôi mã được tạo sẵn để thực hiện đăng ký người dùng, đăng nhập, thay đổi mật khẩu và tất cả.

Bây giờ hãy xem xét chúng ta có 10 ứng dụng khác nhau và không khả thi để làm điều tương tự trong cả 10 ứng dụng. đó là thực hành rất mong manh và rất tồi tệ.

để giải quyết vấn đề này, những gì chúng tôi có thể làm là tập trung Xác thực và ủy quyền của mình để bất cứ khi nào có bất kỳ thay đổi nào với điều này sẽ không ảnh hưởng đến tất cả 10 ứng dụng của chúng tôi.

Máy chủ nhận dạng cung cấp cho bạn khả năng làm điều tương tự. chúng tôi có thể tạo một ứng dụng web mẫu vừa được sử dụng làm dịch vụ Identity và nó sẽ xác thực người dùng của bạn và cung cấp một số mã thông báo truy cập JWT.


2

Tôi đã luôn sử dụng ủy quyền / xác thực ASP.NET Identity (và trước đây là Thành viên), tôi đã triển khai Auth0 gần đây ( https://auth0.com ) và khuyên bạn nên thử điều này như một thứ khác.


Ví dụ về lõi Auth0 .net khá nhanh chóng và đơn giản để triển khai, nhưng việc sử dụng tất cả các tính năng đòi hỏi một chút công việc, tôi đã triển khai Auth0 tích hợp rất nhiều tính năng và nó hoạt động tốt, nhưng giống như tất cả những thứ này, nhu cầu của nó là một chút công việc và một số thất vọng.
Mark Redman

Khi tôi nhận được một xác thực hoạt động tốt, tôi sẽ đăng một câu trả lời chuyên sâu về nó. Tôi vừa làm việc về xác thực tuần qua. Và không có gì là eo biển về phía trước như nó phải là
johnny 5

0

Đăng nhập xã hội không khó để triển khai với Identity, nhưng có một số thiết lập ban đầu liên quan và đôi khi các bước bạn tìm thấy trực tuyến trong tài liệu không giống nhau, thông thường bạn có thể tìm trợ giúp cho điều đó trong phần nhà phát triển của nền tảng bạn đang cố gắng thiết lập đăng nhập xã hội cho. Identity là sự thay thế chức năng thành viên cũ được tìm thấy trong các phiên bản cũ của khung .net. Điều tôi thấy ngạc nhiên là các trường hợp sử dụng cạnh, như chuyển mã thông báo jwt mà bạn đã có đến một api web không được đề cập ở bất kỳ đâu trong các ví dụ trực tuyến ngay cả trên số nhiều, tôi chắc chắn rằng bạn không cần cơ quan cấp mã thông báo của riêng mình để làm điều này nhưng tôi chưa tìm thấy một ví dụ nào về cách chuyển dữ liệu trong một lần nhận hoặc bài đăng không xử lý với máy chủ tự lưu trữ.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.