Phương pháp xác thực Asp.Net Core

Chào mọi người, hiện tại mình đang làm Web API Asp.Net Core. Hiện tại mình đang dùng JWT để xác thực người dùng. Nếu client là ứng dụng điện thoại thì mình sẽ yêu cầu người dùng đăng nhập và refresh access token được rồi. Nhưng mình có thêm một yêu cầu khác là client của Api là một con chatbot. Để chatbot có thể đăng nhập và Refresh Token như mobile thì mình chưa làm được. Nên mình đang nghĩ tới hướng giải quyết là kết hợp cả 2 phương pháp: Phương pháp1: người dùng đăng nhập bằng username và password và sẽ nhận được access token (JWT), phương pháp 2: dùng Client ID để xác thực. Phương pháp 1 thì mình đã làm xong rồi. Còn phương pháp 2 thì giống như API Key, mình sẽ tạo sẵn một key nào đó rồi lưu vào database của api và dùng API Key đó để gọi tới api. Nhưng mình chưa biết cách kết hợp 2 phương pháp trên, nhờ mọi người giúp đỡ hoặc gợi ý cho mình cách khác hiệu quả hơn ạ.

câu hỏi của bạn cứ lang mang như nào ấy

người dùng đăng nhập thì liên quan gì con bot, phương pháp này không đề cập gì để việc xác thực của con but

bạn không nêu rõ, việc xác thực cho con bot có ý nghĩa gì thì ai mà tư vấn cho được

  1. con bot có 1 account, khi gọi api thì dùng account đó? hay khi gọi api thì nó dùng account của user đang sử dụng đó?
  2. việc con bot sử dụng các api đó có tính audit hay không?
  3. Kết hợp với mục đích gì?

bạn không nói rõ thì ai mà biết giải pháp của bạn có được không

3 Likes

xin lỗi mình trình bày hơi lan man. Nhưng có thể hiểu là người dùng muốn dùng bot để gọi api thì người dùng cũng phải đăng nhập vào bot giống như đăng nhập trên điện thoại. Nhưng khó ở chỗ bot khó lưu được access token và refresh token.

Trả lời câu hỏi của bạn ạ.

  1. khi gọi api thì nó dùng account của user đang sử dụng đó (như mình vừa mới nói).
  2. mình chưa rõ câu hỏi lắm
  3. mục đích: muốn xác thực bằng jwt với thời gian expire ngắn phụ hợp nhưng việc người dùng đăng nhập vào bot và việc lưu cũng như refresh token hơi khó nên mình muốn tìm phương pháp mới.

Mình vừa mới nghĩ ra một vấn đề với phương pháp 2 dùng API Key: Nếu dùng API Key thì api sẽ không biết user nào đang gọi mà chỉ biết là bot gọi. Thế nên mình sẽ phải tìm cách nào để người dùng đăng nhập vào bot.

ý 2 là lý do để đưa ra sự lựa chọn ở ý 1
như vậy, để đáp ứng được việc này thì có 2 giải pháp

  1. Vẫn dùng api key, nhưng sẽ gửi kèm theo user chat (ví dụ như để trong header), và con bot phải biết được message đến từ user nào? => vấn đề của bạn tương đương vấn đề in đậm
  2. Con bot dùng account của người dùng, như vậy ngoài việc bot phải biết message nó nhận được đến từ user nào, mà nó còn phải dựa vào đó để lấy ra token của user đó
    phần lưu token của user và lấy ra dựa theo user có thể dung redis để giải quyết

như vậy thì dù là cách gì thì vấn đề vẫn là nhận biết message đến từ user nào, hay nói cách khác là định danh user đang chat với bot (hoặc định danh conversation)
ví dụ như chat bot telegram nó có chat id để định danh conversation, có thể phân biệt các conversation bằng chat id, có thể dùng chat id đó làm key để lưu data trên redis

không biết chat bot của bạn work như nào nên cũng không có gì để bàn thêm

3 Likes

Mình xin trả lời.

  1. con bot phải biết được message đến từ user nào? => đúng ạ. Việc gửi kèm theo user chat như để trong header mình thấy không hợp lý lắm vì phía bot client (channel) có thể là Facebook messenger,… nên những channel ấy không thể gửi kèm gì theo được ngoài những message. Cho nên mình thấy ý 2 của bạn hợp lý hơn.
  2. Mình vừa tìm hiểu được có thể dùng BotClientUserId hoặc ConversationId để lưu và lấy username cũng như access token bằng memory cache rồi. Mình sẽ tìm hiểu thêm về redis. Mính sẽ quyết định đi theo hướng này. Nhưng mình vẫn còn một thắc mắc là phía api sever mình để thời gian expire jwt khá ngắn (1 tiếng) nên access token kia sẽ nhanh bị expire. Bây giờ mình nên tìm hiểu cách Refresh Token ở bot hay là thay đổi cách xác thực ở server ạ.

Nhìn chung, các thành phần tham gia trong câu chuyện này là:
Bạn nên sử dụng key cho bot, bot lúc này được xem như một application client
Lúc này, bạn vẫn cần xác thực cho user khi chém gió với bot trước, tuy nhiên, bạn không cần phải lưu token lại, mục đích chỉ là xác thực thành công bước đầu thôi

Tổng quan vấn đề nó như này
user/chat channel/conversation <-> bot <-> server
(dưới góc nhìn của con bot, thì nó chỉ thấy các conversation)

  • user -> gửi thông tin đăng nhập đến bot (qua chat channel hoặc gì đó khác thì tùy) -> bot nhận được thông tin và gửi sang api login -> thành công và nhận về thông tin user -> bot dùng conversationId làm keylưu thông tin định danh user vào redis
    Sau này chỉ cần dùng conversationId là có thể lấy được thông tin user từ trong redis

  • user sử dụng các lệnh cần đến api -> bot nhận lệnh và gọi api, sử dụng api key cố định, tìm thông tin user từ trong redis bằng conversationId và thêm vào header

Giải pháp trên đáp ứng được vấn đề của bạn

  • Bot luôn luôn gọi đươc api (vì dùng api key cố định)
  • Bot có thể quyết định được thời gian login timeout (tức là phiên login có giá trị trong bao lâu) bằng thiết lập timeout của redis mà không cần phải có bất kì chỉnh sửa ở server, hay thậm chí là 1 session duy nhất cho mỗi user khi gọi bot … (ví dụ như có 2 conversation cùng login 1 account thì đá thằng sau ra…)
5 Likes

À do mình hiểu nhầm phần thêm user header là từ phía channel.
Có nghĩa là mình sẽ đổi phương pháp xác thực ở server. Từ phương pháp xác thực bằng username và password để tạo ra jwt sang phương pháp dùng api key và username. Nếu chuyển qua phương pháp 2 thì cho mình hỏi thêm.

  1. Nếu dùng api key cố định (lưu api key đâu đó trong code) thì tất cả user chat với bot sẽ sử dụng chung api key đó. Nghĩa là user1 sẽ là api key + username1, user2 là api key + username2. Khác nhau chỉ ở username. Vậy chỉ cần username được lưu ở redis thì đều được xác thực thông qua bot nên mình hơi phân vân về tình bảo mật.
  2. Hay là mình không dùng api cố định nữa mà mỗi user khi login bot sẽ lưu lại api key và username của người đó. Như vậy thì api key sẽ là của từng user chứ không phải cố định nữa.
  3. Dùng api key + username để xác thực thì có thể phân quyền được không nhỉ?

Phương pháp 1: gọi là Resource Owner Password. User đăng nhập vào hệ thống
Phương pháp 2: gọi là Client Credentials. Chat bot đăng nhập vào hệ thống

Trong TH bạn muốn user uỷ quyền truy cập cho chatbot bạn cần dùng tới Authorization Code. Chatbot đăng nhập hệ thống dưới quyền User, có thể lấy thông tin, của user, thay mặt user gửi nhận tin nhắn,…

4 Likes

Mục đích cuối cùng là ủy quyền truy cập cho bot đó bạn. Nhưng cách Authorization Code mình không thực hiện được trong trường hợp này. Mình chỉ có thể gửi username và password cho bot thôi chứ không dùng OAuth được.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?