Tại sao mã thông báo truy cập hết hạn?


209

Tôi mới bắt đầu làm việc với Google API và OAuth2. Khi khách hàng ủy quyền cho ứng dụng của tôi, tôi được cấp "mã thông báo làm mới" và "mã thông báo truy cập" tồn tại trong thời gian ngắn. Bây giờ mỗi khi mã thông báo truy cập hết hạn, tôi có thể POST mã thông báo làm mới của mình lên Google và họ sẽ cấp cho tôi mã thông báo truy cập mới.

Câu hỏi của tôi là mục đích của mã thông báo truy cập hết hạn là gì? Tại sao không thể có mã thông báo truy cập lâu dài thay vì mã thông báo làm mới?

Ngoài ra, mã thông báo làm mới hết hạn?

Xem Sử dụng OAuth 2.0 để truy cập Google API để biết thêm thông tin về quy trình làm việc OAuth2 của Google.

Câu trả lời:


226

Điều này rất cụ thể về triển khai, nhưng ý tưởng chung là cho phép các nhà cung cấp phát hành mã thông báo truy cập ngắn hạn với mã thông báo làm mới dài hạn. Tại sao?

  • Nhiều nhà cung cấp hỗ trợ mã thông báo mang rất yếu về bảo mật. Bằng cách làm cho chúng tồn tại trong thời gian ngắn và yêu cầu làm mới, chúng hạn chế thời gian kẻ tấn công có thể lạm dụng mã thông báo bị đánh cắp.
  • Triển khai quy mô lớn không muốn thực hiện tra cứu cơ sở dữ liệu mỗi cuộc gọi API, vì vậy thay vào đó, họ phát hành mã thông báo truy cập tự mã hóa có thể được xác minh bằng cách giải mã. Tuy nhiên, điều này cũng có nghĩa là không có cách nào để thu hồi các mã thông báo này để chúng được phát hành trong một thời gian ngắn và phải được làm mới.
  • Mã thông báo làm mới yêu cầu xác thực ứng dụng khách làm cho nó mạnh hơn. Không giống như các mã thông báo truy cập ở trên, nó thường được triển khai với tra cứu cơ sở dữ liệu.

4
Hai câu hỏi: 1) Trong trường hợp ứng dụng di động, yêu cầu xác thực ứng dụng khách có làm cho nó mạnh hơn không? Vì client_secret là một phần của mã nguồn ứng dụng, nên nó hoàn toàn không bí mật. Giả sử rằng mã thông báo truy cập cũng chỉ được chia sẻ qua TLS (và dấu đầu dòng đầu tiên của bạn không áp dụng) có bảo mật thêm không? 2) Giả sử rằng tất cả điều này giữ trong kịch bản của chúng tôi (chỉ TLS, không có mã thông báo không thể mã hóa tự động), liệu có thể phát hành mã thông báo truy cập không hết hạn không?
Thilo

4
Mã thông báo mang là gì và nó có liên quan gì đến việc làm mới và truy cập mã thông báo?
allyourcode

7
@Thilo Tôi nghĩ rằng ý tưởng là mã thông báo truy cập không cần phải thu hồi. Như Eran chỉ ra, điều này giúp dịch vụ được yêu cầu quyết định có nên phục vụ yêu cầu <em> mà không phải tìm kiếm mã thông báo truy cập trong một số cơ sở dữ liệu </ em> hay không. AFAICT, đó là lợi ích thực sự của việc tách các mã thông báo làm mới và mã thông báo truy cập.
allyourcode

5
Làm thế nào là một mã thông báo truy cập (người mang?) Có thời gian tồn tại ngắn? Nếu tôi thực hiện một yêu cầu với mã thông báo mang đã hết hạn, mã thông báo làm mới sẽ trả lại mã thông báo mang mới. Tương tự, nếu tôi đánh cắp mã thông báo của ai đó từ cookie của họ và giả mạo cookie của riêng tôi bằng mã thông báo đó, tôi sẽ gửi nó đến máy chủ, nó sẽ làm mới và gửi cho tôi một cái mới. Cái gì để ngăn chặn điều đó? Đừng nói Địa chỉ IP hoặc thậm chí MAC, vì điều đó không hợp lý.
Suamere

3
@Suamere, đã được giải thích rồi. Các mã thông báo mang được xác thực bởi một quy trình mật mã không chạm vào cơ sở dữ liệu xác thực, làm cho chúng hiệu quả hơn nhiều đối với việc truy cập tài nguyên thường xuyên. Các mã thông báo làm mới được xác thực trong một quy trình bao gồm kiểm tra cơ sở dữ liệu để đảm bảo rằng nó vẫn còn hiệu lực. Bây giờ hãy nghĩ về cách hoạt động của gmail. Nếu ai đó đăng nhập vào tài khoản của bạn từ một vị trí địa lý bất ngờ, bạn có thể nhận được cảnh báo. Bạn có thể thấy tất cả các vị trí có thể có mã thông báo làm mới hiện tại hợp lệ. Bạn có thể đăng xuất khỏi tất cả các vị trí, làm mất hiệu lực tất cả các mã thông báo làm mới khác.
Bon

33

Một vài tình huống có thể giúp minh họa mục đích truy cập và làm mới mã thông báo và sự đánh đổi kỹ thuật trong việc thiết kế hệ thống oauth2 (hoặc bất kỳ auth nào khác):

Kịch bản ứng dụng web

Trong kịch bản ứng dụng web, bạn có một vài tùy chọn:

  1. nếu bạn có quản lý phiên của riêng mình, hãy lưu trữ cả access_token và refresh_token đối với id phiên của bạn ở trạng thái phiên trên dịch vụ trạng thái phiên của bạn. Khi một người dùng yêu cầu một trang yêu cầu bạn truy cập tài nguyên, hãy sử dụng access_token và nếu access_token đã hết hạn, hãy sử dụng refresh_token để lấy tài nguyên mới.

Hãy tưởng tượng rằng ai đó quản lý để chiếm quyền điều khiển phiên của bạn. Điều duy nhất có thể là yêu cầu các trang của bạn.

  1. nếu bạn không có quản lý phiên, hãy đặt access_token vào cookie và sử dụng nó làm phiên. Sau đó, bất cứ khi nào người dùng yêu cầu các trang từ máy chủ web của bạn gửi access_token. Máy chủ ứng dụng của bạn có thể làm mới access_token nếu cần.

So sánh 1 và 2:

Trong 1, access_token và refresh_token chỉ di chuyển trên dây trên đường giữa máy chủ ủy quyền (google trong trường hợp của bạn) và máy chủ ứng dụng của bạn. Điều này sẽ được thực hiện trên một kênh an toàn. Một hacker có thể chiếm quyền điều khiển phiên nhưng họ chỉ có thể tương tác với ứng dụng web của bạn. Trong 2, tin tặc có thể lấy access_token đi và hình thành các yêu cầu của riêng chúng đối với các tài nguyên mà người dùng đã cấp quyền truy cập. Ngay cả khi tin tặc nắm giữ access_token, chúng sẽ chỉ có một cửa sổ ngắn để chúng có thể truy cập tài nguyên.

Dù bằng cách nào thì máy chủ refresh_token và clientid / secret chỉ được biết đến từ trình duyệt web để có được quyền truy cập dài hạn.

Hãy tưởng tượng bạn đang triển khai oauth2 và đặt thời gian chờ dài cho mã thông báo truy cập:

Trong 1) Không có nhiều khác biệt ở đây giữa mã thông báo truy cập ngắn và dài vì nó được ẩn trong máy chủ ứng dụng. Trong 2) ai đó có thể lấy access_token trong trình duyệt và sau đó sử dụng nó để truy cập trực tiếp vào tài nguyên của người dùng trong một thời gian dài.

Kịch bản di động

Trên điện thoại di động, có một vài tình huống mà tôi biết:

  1. Lưu trữ clientid / bí mật trên thiết bị và để thiết bị phối hợp có được quyền truy cập vào tài nguyên của người dùng.

  2. Sử dụng một máy chủ ứng dụng phụ trợ để giữ clientid / bí mật và để nó thực hiện việc phối hợp. Sử dụng access_token như một loại khóa phiên và chuyển nó giữa máy khách và máy chủ ứng dụng.

So sánh 1 và 2

Trong 1) Khi bạn có clientid / secret trên thiết bị, họ sẽ không còn bí mật nữa. Bất cứ ai cũng có thể dịch ngược và sau đó bắt đầu hành động như thể họ là bạn, với sự cho phép của người dùng tất nhiên. Access_token và refresh_token cũng nằm trong bộ nhớ và có thể được truy cập trên một thiết bị bị xâm nhập, điều đó có nghĩa là ai đó có thể hoạt động như ứng dụng của bạn mà không cần người dùng cung cấp thông tin đăng nhập của họ. Trong kịch bản này, độ dài của access_token không có sự khác biệt nào đối với khả năng hack vì refresh_token nằm cùng chỗ với access_token. Trong 2) clientid / secret hay mã thông báo làm mới đều bị xâm phạm. Ở đây thời hạn của access_token hết hạn xác định thời gian tin tặc có thể truy cập tài nguyên của người dùng, nếu họ nắm giữ được.

Thời hạn sử dụng

Ở đây, nó phụ thuộc vào những gì bạn đang bảo mật với hệ thống xác thực của mình về thời gian truy cập access_token của bạn sẽ là bao lâu. Nếu nó là thứ gì đó đặc biệt có giá trị với người dùng thì nó nên ngắn gọn. Một cái gì đó ít giá trị, nó có thể được lâu hơn.

Một số người như google không hết hạn refresh_token. Một số như stackflow làm. Quyết định về thời hạn sử dụng là sự đánh đổi giữa sự dễ dàng và bảo mật của người dùng. Độ dài của mã thông báo làm mới có liên quan đến độ dài trả lại của người dùng, tức là đặt làm mới thành tần suất người dùng quay lại ứng dụng của bạn. Nếu mã thông báo làm mới không hết hạn, cách duy nhất chúng bị thu hồi là thu hồi rõ ràng. Thông thường, một bản ghi trên sẽ không thu hồi.

Hy vọng rằng bài viết khá dài là hữu ích.


về MOBILE SCENARIO sẽ không thành vấn đề nếu bạn lưu trữ id khách hàng trong máy chủ của mình. vì vậy, bất kỳ ứng dụng nào khác chỉ có thể gửi yêu cầu đến máy chủ của bạn và có thể truy cập tài nguyên người dùng thông qua máy chủ của bạn, cũng vậy
Amir Bar

đúng, nhưng sau đó họ chỉ có quyền truy cập vào các cơ sở bạn cung cấp, thay vì truy cập đầy đủ vào mã thông báo cơ bản. Tức là họ có thể mạo danh ứng dụng của bạn. Thông thường, các mã thông báo có thể có quyền rộng, trong khi bạn chỉ yêu cầu một tập hợp con. Giữ mã thông báo trong phần phụ trợ cung cấp thêm hạn chế, nếu bạn cần.
Ed Sykes

11

Ngoài các phản hồi khác:

Sau khi có được, Mã thông báo truy cập thường được gửi cùng với mọi yêu cầu từ Máy khách đến Máy chủ tài nguyên được bảo vệ. Điều này gây ra rủi ro cho việc đánh cắp và phát lại mã thông báo truy cập (tất nhiên giả sử rằng mã thông báo truy cập thuộc loại "Người mang" (như được định nghĩa trong RFC6750 ban đầu).

Ví dụ về những rủi ro đó, trong cuộc sống thực:

  • Máy chủ tài nguyên thường là các máy chủ ứng dụng phân tán và thường có mức bảo mật thấp hơn so với Máy chủ ủy quyền (cấu hình SSL / TLS thấp hơn, ít cứng hơn, v.v.). Mặt khác, Máy chủ ủy quyền thường được coi là cơ sở hạ tầng Bảo mật quan trọng và có thể bị cứng nghiêm trọng hơn.

  • Mã thông báo truy cập có thể hiển thị trong các dấu vết HTTP, nhật ký, v.v. được thu thập hợp pháp cho mục đích chẩn đoán trên Máy chủ tài nguyên hoặc máy khách. Những dấu vết đó có thể được trao đổi qua các địa điểm công cộng hoặc bán công khai (bộ theo dõi lỗi, bàn dịch vụ, v.v.).

  • Các ứng dụng Backend RS có thể được gia công cho các bên thứ ba đáng tin cậy hơn hoặc ít hơn.

Mặt khác, Mã thông báo làm mới thường chỉ được truyền hai lần qua các dây và luôn luôn giữa máy khách và Máy chủ ủy quyền: một lần khi được khách hàng lấy và một lần khi được khách hàng sử dụng trong quá trình làm mới ("hết hạn" một cách hiệu quả mã thông báo). Đây là một cơ hội hạn chế đáng kể để đánh chặn và phát lại.

Suy nghĩ cuối cùng, Mã thông báo làm mới cung cấp rất ít sự bảo vệ, nếu có, chống lại các khách hàng bị xâm nhập.


Bạn có phần cảm động về điều này, nhưng tôi sẽ nhấn mạnh rằng bề mặt tấn công lớn hơn để có được các mã thông báo (hoặc ngược lại vô tình tiết lộ) là trong nhật ký ứng dụng hoặc các dịch vụ tài nguyên được thêm vào một cách bất chính (không phải là một cuộc tấn công MITM ngày nay). Gần như mọi nơi trong một phụ trợ API phổ biến đều có quyền truy cập vào mã thông báo truy cập được sử dụng (nếu nó có quyền truy cập vào đối tượng HttpRequest, v.v.). Chỉ các đường dẫn mã TWO trong hệ thống mới có quyền truy cập vào mã thông báo làm mới - đường dẫn tạo mã này ở vị trí đầu tiên và đường dẫn trao đổi mã thông báo truy cập mới. Đó là một sự khác biệt đáng kể bề mặt tấn công.
Tom Dibble

9

Nó thực chất là một biện pháp an ninh. Nếu ứng dụng của bạn bị xâm nhập, kẻ tấn công sẽ chỉ có quyền truy cập vào mã thông báo truy cập ngắn hạn và không có cách nào để tạo một mã mới.

Làm mới mã thông báo cũng hết hạn nhưng chúng được cho là tồn tại lâu hơn nhiều so với mã thông báo truy cập.


45
Nhưng kẻ tấn công cũng không có quyền truy cập vào mã thông báo làm mới? và có thể sử dụng điều đó để tạo mã thông báo truy cập mới không?
levi

10
@levi, tin tặc không thể sử dụng mã thông báo làm mới để tạo mã thông báo truy cập mới vì ID khách hàng và bí mật khách hàng là cần thiết cùng với mã thông báo làm mới để tạo mã thông báo truy cập mới.
Spike

9
@Spike Đúng, nhưng ứng dụng có id khách hàng và bí mật được nhúng trong đó không?
Andy

9
Vì vậy, nó cung cấp một số bảo vệ khỏi việc đánh hơi gói tin, miễn là việc chặn chỉ bắt các yêu cầu dữ liệu thông thường (Chuck chỉ nhận được mã thông báo truy cập)? Nghe có vẻ hơi yếu; mũ đen chỉ cần chờ một chút cho đến khi người dùng yêu cầu mã thông báo truy cập mới và sau đó anh ta sẽ nhận được ID khách hàng, bí mật và mã thông báo làm mới.

3
Điều này có thể chỉ là tôi bị chậm phát triển ở đây, nhưng nếu điều này được gửi qua SSL thì điều đó không thêm vào một lớp bảo mật có thể khác. Tôi đoán tôi đang giả sử mọi người đều biết SSL là gì.
Damon Drake
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.