29

Tôi đang triển khai dịch vụ web RESTful bằng ASP.Net Web Api. Tôi đã kết luận sử dụng Basic authentication + SSL để thực hiện phần xác thực. Cách tốt nhất/chính xác để thực hiện điều đó là gì?API Web ASP.net Dịch vụ web RESTful + Xác thực cơ bản

Nỗ lực đầu tiên của tôi là thực hiện thủ công, phân tích cú pháp tiêu đề Cấp phép, giải mã và xác minh người dùng dựa vào cơ sở dữ liệu của tôi. Nó hoạt động, nhưng tôi tự hỏi nếu tôi đang thiếu một cái gì đó.

Tôi đã xem một số giải pháp sử dụng vai trò người dùng và hiệu trưởng. Trong khi tôi không chắc chắn những gì thực sự làm, tôi gần như chắc chắn tôi sẽ không cần những, kể từ trong cơ sở dữ liệu của tôi, tôi xác định người dùng của riêng tôi và vai trò của họ.

Ngoài ra những gì tôi chưa hiểu hoàn toàn, là nếu người tiêu dùng dịch vụ phải gửi thông tin đăng nhập với mỗi yêu cầu hoặc chúng được lưu trữ bằng cách nào đó. Dịch vụ của tôi có nên làm điều gì đó để điều này xảy ra hay hoàn toàn phụ thuộc vào người tiêu dùng để xử lý việc này?

Và câu hỏi cuối cùng về khách hàng đưa ra yêu cầu với javascript. Sẽ có bất kỳ vấn đề "yêu cầu tên miền chéo" nào nếu họ cố gắng sử dụng dịch vụ?

Trả lời

25

Jamie Kurtze cung cấp một lời giải thích tốt của việc sử dụng Basic Authentication đây ASP.NET Web API REST Security Basics

Từ hiểu biết của tôi, nếu bạn muốn yêu cầu của bạn trở thành quốc tịch thì mỗi yêu cầu sẽ yêu cầu e trường Xác thực sẽ được đặt

Jamie Kurtze bao bọc mã cần thiết trong lớp có nguồn gốc từ DelegateHandler, trong khi Rick Strahl kiểm tra xem cuộc gọi có hợp lệ hay không bằng Bộ lọc. Bạn có thể đọc thêm tại bài đăng trên blog của mình về chủ đề này tại A WebAPI Basic Authentication Authorization Filter

+0

Xin chào, khi tôi viết câu hỏi, không rõ ràng về cách thức các Hiệu trưởng và Vai trò được sử dụng (và chúng liên quan đến người dùng của tôi như thế nào). Những gì tôi làm bây giờ là sử dụng tiêu đề xác thực để truyền các thông tin đăng nhập và một mô-đun Http để kiểm tra thống nhất cho chúng. Tôi sẽ xem xét các liên kết của bạn khi tôi có thời gian. – alfoks

+0

Triển khai của tôi hoạt động tốt ngay bây giờ, nhưng đây là những liên kết tốt cho người đọc trong tương lai. – alfoks

+1

Liên kết đầu tiên của bạn về ASP.NET Web Api REST Security Basics đã chết –

1

Có một cái nhìn vào đây để xem cơ bản thực hiện tốt xác thực

http://leastprivilege.com/2013/04/22/web-api-security-basic-authentication-with-thinktecture-identitymodel-authenticationhandler/

có nhiều hơn để đọc về nó tại địa chỉ: https://github.com/thinktecture/Thinktecture.IdentityModel.45/wiki

+0

Các liên kết này không thực sự trả lời câu hỏi của tôi. Chỉ có câu hỏi đầu tiên có thể, nhưng chúng đề cập đến việc cấu hình thư viện bảo mật của bên thứ ba. Do thiếu thời gian, tôi muốn tránh sử dụng nhiều thư viện hơn. – alfoks

21

Sử dụng xác thực cơ bản cho yêu cầu ban đầu (đăng nhập) bằng cách thêm thuộc tính [BasicHttpAuthorize] vào bộ điều khiển/phương pháp phù hợp. Chỉ định UsersRoles với thuộc tính nếu muốn. Xác định BasicHttpAuthorizeAttribute như một chuyên AuthorizeAttribute như thế này:

public class BasicHttpAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override bool IsAuthorized(HttpActionContext actionContext) 
    { 
     if (Thread.CurrentPrincipal.Identity.Name.Length == 0) { // If an identity has not already been established by other means: 
      AuthenticationHeaderValue auth = actionContext.Request.Headers.Authorization; 
      if (string.Compare(auth.Scheme, "Basic", StringComparison.OrdinalIgnoreCase) == 0) { 
       string credentials = UTF8Encoding.UTF8.GetString(Convert.FromBase64String(auth.Parameter)); 
       int separatorIndex = credentials.IndexOf(':'); 
       if (separatorIndex >= 0) { 
        string userName = credentials.Substring(0, separatorIndex); 
        string password = credentials.Substring(separatorIndex + 1); 
        if (Membership.ValidateUser(userName, password)) 
         Thread.CurrentPrincipal = actionContext.ControllerContext.RequestContext.Principal = new GenericPrincipal(new GenericIdentity(userName, "Basic"), System.Web.Security.Roles.Provider.GetRolesForUser(userName)); 
       } 
      } 
     } 
     return base.IsAuthorized(actionContext); 
    } 
} 

Có phản ứng ban đầu bao gồm một khóa API cho người dùng. Sử dụng khóa API cho các cuộc gọi tiếp theo. Bằng cách đó, xác thực của khách hàng vẫn hợp lệ ngay cả khi người dùng thay đổi tên người dùng hoặc mật khẩu. Tuy nhiên, khi thay đổi mật khẩu, hãy cung cấp cho người dùng tùy chọn "ngắt kết nối máy khách" mà bạn thực hiện bằng cách xóa khóa API trên máy chủ.

+0

Tôi đã giải quyết được vấn đề nhưng cảm ơn bạn đã trả lời. Tôi thấy nó dễ dàng hơn để vượt qua, trong tất cả các cuộc gọi API, tên người dùng và mật khẩu trong tiêu đề Cấp quyền, thay vì sử dụng phương thức mã thông báo mà bạn đề xuất. – alfoks

+0

@Edward Cảm ơn rất nhiều bài viết của bạn, tôi thấy nó trợ giúp nhiều nhất. Bạn đang sử dụng cơ chế vai trò và người dùng nào trong ví dụ này? Tôi thấy bạn tạo ra một GenericPrinsiple mới. Bạn có thể quan tâm để xây dựng cách tôi tích hợp giải pháp của bạn vào một dự án api web trống mới. – Zapnologica

+0

@Zapnologica Mã này sử dụng mô hình nhận dạng thành viên cũ mà Microsoft đã sử dụng trước VS2013. Các mẫu với VS2013 sử dụng hệ thống nhận dạng dựa trên OWIN mới, thực hiện xác thực tên người dùng/mật khẩu tùy chỉnh theo sau bằng cách sử dụng các mã thông báo mang, loại bỏ sự cần thiết của BasicHttpAuthorize. –

Các vấn đề liên quan