Làm thế nào để kiến ​​trúc sư xác thực người dùng từ các ứng dụng khách?


14

Tôi đã phát triển một ứng dụng sẽ hỗ trợ nhiều người dùng. Vấn đề là tôi không thể tìm ra cách xác thực ứng dụng khách / người dùng.

Tôi đang xây dựng một ứng dụng như http://quickblox.com/ nơi tôi sẽ cung cấp thông tin cho người dùng của tôi và họ sẽ sử dụng để xây dựng những tồn các ứng dụng mà họ không thể đặt tên truy cập và mật khẩu của họ để có được chứng thực.

Hãy giả sử nó đi như sau. (Giống như QuickBlox)

1. Người dùng tạo tài khoản trên trang web của tôi.
2. Người dùng có thể tạo khóa N API và tiết lộ thông tin đăng nhập. (Đối với nhiều ứng dụng)
3. Người dùng sẽ sử dụng các thông tin đăng nhập này trong các ứng dụng của họ (Android, iOS, Javascript, v.v.) để nói chuyện với API REST của tôi.
(API REST có quyền truy cập đọc và ghi.)

Nỗi lo của tôi?

Người dùng sẽ đặt thông tin đăng nhập của họ (khóa API và khóa bí mật) trong các ứng dụng họ xây dựng, nếu ai đó nhận được các khóa này và cố gắng bắt chước người dùng thì sao? (Bằng cách dịch ngược APK hoặc trực tiếp tìm mã JavaScript.

Tôi có sai ở đâu đó không?
Tôi bối rối để kiến ​​trúc sư cơ chế người dùng ba cấp này.


Điều mà bạn dường như đang cố gắng làm là không thể.
dùng253751

Có rất nhiều ứng dụng ngoài kia làm điều tương tự. Tôi không chắc làm thế nào để họ xác thực người dùng.
Alok Patel

Bạn đang cố gắng xác thực ứng dụng khách hay người dùng ? Rất nhiều ứng dụng xác thực người dùng. Không ai trong số họ xác thực các ứng dụng khách theo cách không thể phá vỡ.
dùng253751

Vâng bởi khách hàng, ý tôi là tôi chỉ muốn xác thực người dùng.
Alok Patel

4
Ồ, vậy thì trong hệ thống xác thực điển hình nhất, bạn chỉ cần người dùng nhập tên người dùng và mật khẩu của họ và gửi chúng một cách an toàn đến máy chủ kiểm tra chúng và (an toàn) trả lại mã thông báo phiên, sau đó bạn gửi mã thông báo phiên mọi yêu cầu trong tương lai.
dùng253751

Câu trả lời:


7

Tôi đã thiết kế API REST trong vài năm qua. Bạn đang lo lắng quá nhiều. Gần đây, một người dùng khác trong diễn đàn này đã hỏi một câu hỏi, nơi anh ta lo lắng về việc lưu trữ các điểm cuối URI trong mã phía máy khách JavaScript của mình .

Các quy tắc tương tự áp dụng cho bạn như áp dụng cho nhà phát triển JavaScript. Nếu bạn cho phép mọi người từ bên ngoài tích hợp API của mình, API của bạn có khả năng hiển thị giống như một trang web thông thường và bạn nên đối xử với nó theo cùng một cách.

Trích dẫn từ câu trả lời ban đầu:

Khi bạn đang tạo một trang web và bạn không muốn người dùng làm điều gì đó, bạn không thực hiện chức năng đó hoặc cấm một số người dùng sử dụng nó. Với API REST cần có các điểm cuối công khai, nó khá giống nhau, bạn cần coi nó như một trang web công cộng.

API REST của bạn phải đủ mạnh để không cho phép các hoạt động không hợp lệ, chẳng hạn như truy cập dữ liệu từ một người dùng khác.

Bạn nên thiết kế mã thông báo truy cập ứng dụng của mình để chỉ cho phép các hoạt động mà bạn muốn được cho phép. Bạn có thể có hai loại mã thông báo truy cập:

  • mã thông báo chính : có thể được người tạo ứng dụng sử dụng và cung cấp thêm chức năng từ API của bạn,
  • mã thông báo ứng dụng : mã thông báo thực sự sẽ được lưu trữ trong các ứng dụng và sẽ chỉ có quyền truy cập hạn chế vào API của bạn, chỉ cho các hoạt động không thể làm hỏng dữ liệu của bạn hoặc lập trình viên ứng dụng.

Nhưng những gì ai đó giải mã mã nguồn, lấy mã thông báo ra khỏi ứng dụng, tìm ra các điểm cuối công khai là gì và lạm dụng dịch vụ web của bạn?

Trừ khi bạn trực tiếp quản lý việc phát triển các ứng dụng tiêu thụ API của mình, không có gì thực sự cấm mọi người lạm dụng API của bạn theo cùng một cách trực tiếp từ ứng dụng.


Giải thích tốt cho đến nay, tôi có một câu hỏi mặc dù. Giả sử một trong số API của tôi được xây dựng để tìm nạp tất cả dữ liệu liên quan (A + B) của người dùng của tôi . Người dùng của tôi sử dụng API này trong ứng dụng của anh ấy để chỉ lấy filtered data(B) người dùng của anh ấy . Bây giờ là có thể, hoặc có bất kỳ cách giải quyết nào để ngăn người dùng thứ ba đánh cắp tất cả dữ liệu (A + B) của người dùng của tôi . Liệu nó có ý nghĩa?
Alok Patel

@AlokPatel Không có cách giải quyết nào khác sau đó chỉ đơn giản là không thực hiện chức năng. Khi bạn làm như vậy, sẽ luôn có nguy cơ ai đó giả mạo băm nhận dạng của anh ta để trông giống người khác. Lập trình vấn đề của bạn không thể được giải quyết. Như tôi đã nói, nếu bạn không muốn cung cấp một số chức năng, đừng thực hiện nó. Vì các ứng dụng có thể sẽ lưu trữ hàm băm đăng nhập bên trong chúng, một khi ứng dụng được triển khai, khóa API của bạn cũng vậy và nó không có sẵn công khai.
Andy

Cảm ơn đã giải thích. Vì vậy, những gì tôi nhận được cho đến nay là các API REST giống như bất kỳ trang web nào chúng tôi triển khai chúng đều mở như trang web. Nếu tôi không muốn người dùng làm điều gì đó thì đơn giản là tôi không thực hiện nó trong API REST của mình. Vì vậy, những gì tôi có thể làm là có các khóa riêng cho các thư viện máy khách (Android, iOS, JS) có thể bị xâm phạm với ít chức năng hơn và các khóa khác nhau sẽ được sử dụng phía máy chủ (PHP, Java, node.js) với chức năng mở rộng. Hy vọng điều này sẽ làm việc!
Alok Patel

Bạn có thể giải thích cho tôi điểm này của bạn? Trừ khi bạn trực tiếp quản lý việc phát triển các ứng dụng tiêu thụ API của mình
Alok Patel

@AlokPatel Ý tôi là, ngay bây giờ bạn đang lo lắng rằng bạn cấp cho ai đó quyền truy cập vào API, họ có thể phân phối quyền truy cập và bắt đầu lạm dụng API. Nếu bạn không kiểm soát được việc phát triển các ứng dụng tiêu thụ API của mình, chúng có thể tự làm tương tự.
Andy

5

Vấn đề của bạn không phải là một vấn đề kỹ thuật nhiều như một doanh nghiệp.

Hãy nói rằng bạn có API của mình, mà bạn bán cho khách hàng của mình (nhà phát triển ứng dụng) với mức giá cố định là 100 bảng mỗi năm, truy cập không giới hạn.

Rõ ràng, tôi có thể mua dịch vụ của bạn với giá 100 bảng và bán cho 10 người với giá 50 đô la mỗi cái. Bạn không muốn điều đó! vì vậy bạn cố gắng nghĩ ra một hạn chế sẽ cho phép bạn bán API của mình mà không bị mở để phân xử.

  • Nếu bạn chỉ giới hạn số lượng Ứng dụng, khách hàng có thể tạo một ứng dụng duy nhất chấp nhận kết nối từ các ứng dụng khác và chuyển chúng vào.

  • Nếu bạn giới hạn người dùng, một lần nữa, khách hàng có thể ẩn người dùng đằng sau xác thực của chính mình và dường như là một người dùng duy nhất.

Những gì bạn cần làm là chuyển chi phí của mỗi lệnh gọi API cho khách hàng của bạn. tức là tính phí cho mỗi cuộc gọi API hoặc đặt hạn mức cuộc gọi mỗi năm.

Điều này đẩy cùng một vấn đề về chênh lệch giá lên khách hàng của bạn. Nó buộc họ phải đưa ra biện pháp để ngăn chặn người dùng của họ lấy cắp chìa khóa của họ. Trong trường hợp này, ẩn api của bạn đằng sau api xác thực người dùng của họ.


Tôi đã lên kế hoạch để hạn chế việc sử dụng API của mình dựa trên số lượng cuộc gọi API để vấn đề liên quan đến kinh doanh không phải là vấn đề của tôi vào lúc này, tôi chỉ quan tâm đến việc các khóa bị đánh cắp.
Alok Patel

Từ quan điểm kinh doanh, vấn đề là không thể giải quyết. Đáng buồn thay, bạn cũng không thể giải quyết nó bằng lập trình.
Andy

1
Các proble kinh doanh. Được giải quyết bằng cách tính phí trên mỗi cuộc gọi. Nếu chìa khóa bị đánh cắp, khách hàng của bạn sẽ mất. Không phải bạn. Chỉ cần cung cấp cho khách hàng của bạn một cách để hủy các khóa bị đánh cắp và nói với họ để có một api trung gian để ngăn chặn lạm dụng
Ewan

2

Các câu trả lời khác dường như đều gợi ý rằng vấn đề lưu trữ bí mật trong một ứng dụng trên các thiết bị tiêu dùng là không thể giải quyết được.

Chắc chắn đó là.

Hai nguyên tắc (chi tiết thực hiện sẽ tuân theo):

  1. Các điểm cuối xác thực thực tế cần được ẩn danh công khai.
  2. Máy chủ phải bằng cách nào đó phải tham gia vào việc xác thực ứng dụng khách và cung cấp khóa API.

Do đó, nếu máy khách đưa ra yêu cầu đến điểm cuối xác thực bằng thông tin xác thực và máy chủ xác thực nó, máy chủ có thể tạo mã thông báo tạm thời động (tạm thời dựa trên thời gian). Mã thông báo này cần được ghi nhớ trong máy khách và được gửi với các yêu cầu tiếp theo.

Bạn sẽ cần một cơ chế để định kỳ "làm mới" mã thông báo, nghĩa là lấy một cái mới. Chỉ cần xây dựng điểm cuối REST cho phép tạo mã thông báo mới từ mã hiện có, để tránh phải xác thực lại từ thông tin đăng nhập.

Nếu bạn đang cố gắng tránh người dùng cuối tự xác thực lại thì xác thực này có thể là thiết lập một lần đầu tiên trong ứng dụng khi được cài đặt.

Giải pháp này chỉ đơn giản là tránh sự cần thiết phải lưu trữ mã thông báo tĩnh được nhúng trong tệp nhị phân của ứng dụng. Một mã thông báo được tạo bởi máy chủ chỉ khi đáp ứng với xác thực thành công. Để người dùng độc hại kiểm tra ứng dụng của bạn và cố gắng truy cập API trái phép, họ vẫn cần xác thực giống như bất kỳ ai khác.


Giải pháp thú vị, mặc dù chủ yếu dựa vào cách khách hàng của OP sẽ mã hóa ứng dụng của họ. Điều này cho biết, cách tiếp cận được đề xuất có thể cho phép lưu trữ phía máy chủ khóa API và sau khi xác thực thành công người dùng của chính họ có thể chuyển tiếp khóa tạm thời cho ứng dụng thực tế sử dụng. cách này không có gì được lưu trữ trong ứng dụng.
Newtopian

Điều đó đúng với tất cả các API. Nếu người tiêu dùng API không sử dụng đúng cách, mọi thứ có thể không hoạt động. Đây sẽ phải là một phần tài liệu của API.
Brandon

Nhân tiện, có các tiêu chuẩn để giúp làm điều này dễ dàng hơn, như OAuth.
Brandon

0

Nếu bạn có các khóa trên mỗi ứng dụng duy nhất, bạn chỉ có thể sử dụng các khóa đó trong khi xác thực kết nối ban đầu, do khách hàng khởi tạo, sau đó bạn chuyển sang mã thông báo xác thực duy nhất cho mỗi ứng dụng.

Thỉnh thoảng, máy chủ của bạn thay đổi (cuộn) mã thông báo cho từng ứng dụng khách (ví dụ cộng / trừ một số độ trễ ngẫu nhiên / mờ ngẫu nhiên). Mã thông báo chỉ được biết giữa máy chủ và máy khách được xác thực.

Các mã thông báo mới được trả lại dựa trên các câu trả lời thông thường. Bất cứ khi nào câu trả lời chứa mã thông báo mới, ứng dụng nhận cần chuyển sang sử dụng nó trong các yêu cầu tiếp theo.

Bất cứ khi nào trao đổi với khách hàng không đồng bộ (một số lỗi giao thức nào đó), máy chủ của bạn sẽ yêu cầu xác thực lại (thông qua phản hồi lỗi cho yêu cầu của khách hàng tiếp theo, hoặc ủng hộ phản hồi hợp lệ cho yêu cầu của khách hàng, cho thí dụ).

Xác thực ban đầu được khởi tạo bởi khách hàng trong khi mã thông báo đang được sử dụng tích cực nên được xem xét với sự nghi ngờ - rất có thể là một nỗ lực bắt chước. Tôi chỉ cho phép nó nếu việc trao đổi không hoạt động trong khoảng thời gian dài hơn dự kiến, ví dụ, có thể do sự cố ngừng hoạt động / khởi động lại của khách hàng với một phiên bản mới không có mã thông báo.

Sẽ tốt hơn nữa nếu duy trì mã thông báo ở phía máy khách để máy khách được khởi động lại có thể tiếp tục từ nơi mà người tiền nhiệm của nó rời đi - thu hẹp đáng kể việc mở để bắt chước.

Sơ đồ như vậy sẽ khiến việc bắt chước ít nhất trở nên khá khó khăn - ứng dụng khách bắt chước sẽ phải dự đoán chính xác cửa sổ khi máy khách được ủy quyền dừng gửi yêu cầu đủ lâu để máy chủ quyết định chấp nhận xác thực ứng dụng khách mới với khóa được chỉ định. Các yêu cầu như vậy bên ngoài cửa sổ được phép có thể được sử dụng để phát hiện các nỗ lực bắt chước và có thể bắt đầu một số biện pháp đối phó (danh sách đen IP, v.v.).


0

Từ những gì tôi biết, những gì bạn đề cập là cách duy nhất để làm điều này. Ứng dụng lưu trữ khóa chắc chắn là một rủi ro, nhưng có nhiều cách khác nhau để phá vỡ nó. Bạn luôn có thể sử dụng kho khóa để lưu trữ khóa, hơn mã hóa cứng, do đó buộc phải đăng nhập một lần.

Ngoài ra, bạn nên xem xét việc ràng buộc một khóa với máy khách, do đó, nếu ai đó bắt chước, bạn nên có một lớp bảo mật để kiểm tra máy khách, khóa và tác nhân người dùng để chặn yêu cầu ngay lập tức. Có một trường hợp sử dụng để cấp lại hoặc đảm bảo lại rằng các khóa không được bắt chước.


JavaScript là gì? Làm thế nào để kiến ​​trúc sư cho điều đó?
Alok Patel

Tôi giả sử bạn đang nói về việc tạo một ứng dụng lai. Nếu đó là trường hợp, thì chắc chắn bạn sẽ có thể tạo một plugin để lưu trữ các khóa. Nếu bạn định lưu trữ ứng dụng và nói về giải pháp web trên thiết bị di động, hãy suy nghĩ về việc hiển thị trang bằng cách sử dụng bộ chứa và bạn có thể dựa vào mã thông báo phiên được đề xuất trước đó
Arun

Không, không phải vậy. Tôi sẽ là nhà cung cấp API hàng đầu thứ ba, người dùng của tôi sẽ sử dụng dịch vụ API của tôi trong các ứng dụng của họ. Nó có thể là Android, iOS, JavaScript, v.v ...
Alok Patel

0

Nếu bạn phụ thuộc vào việc cấp mã thông báo ủy quyền cho khách hàng của mình để đưa vào ứng dụng của họ, về mặt lý thuyết, người nào đó sẽ luôn có thể đảo ngược ứng dụng và trích xuất chúng. Để ngăn chặn điều này, bạn sẽ cần một cơ chế không yêu cầu bí mật trong ứng dụng khách. Đó là khó khăn. Tôi có thể đề xuất một số tùy chọn để bạn suy nghĩ về mặc dù.

Bạn gặp vấn đề khi bạn đã cung cấp thông tin đăng nhập, bạn không kiểm soát được mức độ an toàn của chúng được lưu trữ. Ngoài ra, nếu bạn yêu cầu người dùng gửi thông tin đăng nhập cho bạn thì ai đó có thể MITM kết nối của bạn và lấy cắp mã thông báo trực tiếp mà không cần bận tâm về kỹ thuật đảo ngược ứng dụng.

Một cách làm cho việc trích xuất mã thông báo ủy quyền của bạn trở nên khó khăn hơn là làm xáo trộn nó. Điều này chỉ làm tăng thanh, nhưng không làm cho nó không thể, và để làm điều đó bạn sẽ phải giữ quyền kiểm soát bí mật. Bạn có thể triển khai một thư viện chứa thông tin bí mật và dành riêng cho từng khách hàng. Bạn có thể sử dụng thư viện để liên lạc với máy chủ của mình và thậm chí bạn có thể không phải cho người dùng biết thông tin bí mật, nó chỉ có thể được nhúng trong thư viện. Điều này không giải quyết được vấn đề ai đó đảo ngược kỹ thuật thư viện của bạn, nhưng nó giúp bạn kiểm soát mức độ khó hiểu. Một nhược điểm là một khi một người đã phá vỡ sự xáo trộn trong thư viện, họ có thể tấn công bất kỳ thư viện nào của bạn, trừ khi bạn viết mã khiến mỗi thư viện khác nhau đáng kể. Điều đó giới thiệu bộ vấn đề của riêng mình.

Điều này có thể đi lạc một chút từ phạm vi câu hỏi của bạn, nhưng nó có liên quan đến tính bảo mật của mã thông báo của bạn vì vậy tôi sẽ đề cập đến nó. Để ngăn chặn hành vi trộm cắp tầm thường của mã thông báo qua dây, bạn có thể không muốn gửi mã thông báo trực tiếp, thay vào đó bạn có thể ký lưu lượng truy cập bằng chức năng HMAC. Bạn có thể kiểm tra tính hợp lệ của tin nhắn bằng cách tính toán HMAC của tin nhắn trên máy chủ và so sánh nó với HMAC được gửi từ máy khách. Bạn sẽ sử dụng mã thông báo làm chìa khóa cho chức năng HMAC để chỉ những người biết mã thông báo mới có thể đăng nhập lưu lượng. Điều này tốt hơn cho việc bảo mật mã thông báo của bạn vì bạn không bao giờ gửi trực tiếp đến máy chủ để nó không thể bị chặn và đánh cắp trực tiếp. Để biết thêm thông tin về HMACS, hãy xem câu hỏi này: /security/20129/how-and-when-do-i-use-hmac/20301

Không có giải pháp bảo mật nào là bất khả xâm phạm, bạn phải quyết định sẽ tốn bao nhiêu tiền để thực hiện so với khả năng và chi phí bị xâm phạm.


Tôi không thể tạo một thư viện và đặt các bí mật trong đó, chúng sẽ khác nhau đối với mỗi người dùng của tôi.
Alok Patel

Để làm rõ, tôi đã đề nghị bạn có thể xây dựng một thư viện tùy chỉnh cho mỗi người dùng của bạn và ẩn các bí mật cá nhân của họ bên trong thư viện. Bạn sẽ cần phải viết một hệ thống để tạo các thư viện tự động theo yêu cầu cho mỗi người dùng mới có thể làm việc nhiều hơn bạn muốn làm.
ThePragmatist

0

Trích dẫn bản thân:

Tôi không thể tìm ra cách xác thực ứng dụng khách / người dùng ... trong đó họ không thể đặt tên người dùng và mật khẩu để được xác thực.

Bây giờ đó là một chút mâu thuẫn, phải không? ;)

Như những người khác nói, bạn không thể. Nếu một ứng dụng sử dụng khóa API, người ta có thể dịch ngược nó như bạn nói để lấy (các) khóa đó và cũng sử dụng nó.

Ngoài việc yêu cầu xác thực người dùng phù hợp bổ sung, bạn chỉ có thể hạn chế thiệt hại:

  • IP danh sách trắng / danh sách đen
  • tiết lưu
  • Phát hiện "hoạt động bất thường" và nguồn của nó
  • đổi mới chìa khóa dễ dàng
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.