2012-01-15 31 views
7

Tôi có một ứng dụng web cần cho phép người dùng sử dụng các webclients khác nhau (trình duyệt, ứng dụng di động gốc, v.v.) để đăng ký. Sau khi đăng nhập, họ có thể truy cập nội dung bị hạn chế hoặc nội dung của riêng họ (như mục họ tạo, v.v.).jax-rs xác thực và cấp phép webservice còn lại

Những gì tôi đã làm như vậy cho đến nay: Tôi tạo ra một jax-rs còn lại webservice (Tôi đang lưu trữ ứng dụng của tôi trên glassfish) mà đưa ra phương án sau:

  • đăng ký - sử dụng POST của mình tên mong muốn/mật khẩu/email/etc; nếu tên người dùng/email là duy nhất, mục nhập cho người dùng này được tạo trong cơ sở dữ liệu (tôi đang sử dụng Hibernate để kiên trì)
  • thông tin đăng nhập - tên người dùng và mật khẩu của người dùng POST. Nếu chúng được chấp nhận, một UUID sẽ được tạo và trả về cho người dùng (điều này sẽ được sử dụng như một mã thông báo cho các yêu cầu trong tương lai). Tôi có một bảng gọi là logedusers, với userID, token, validSince dưới dạng cột.

Đây là nơi nó gây nhầm lẫn cho tôi.

Giả sử tôi có phương thức khác, getUserEntries, sẽ trả về tất cả các mục nhập do người dùng tạo. Để làm cho điều này rõ ràng hơn, sẽ có một bảng Entry với các trường sau: entryId, userId, văn bản.

Cách tiếp cận tốt nhất ở đây là gì?

gì tôi làm bây giờ, là tôi thực hiện một yêu cầu get và vượt qua trong các dấu hiệu như thế này:

localhost:8080/myApp/getUserEntries?token=erf34c34

Sau đó, nếu thẻ có giá trị, tôi nhận được userID từ bảng logedusers Döïa trên userId đó, nhận tất cả các mục nhập và trả về chúng dưới dạng json.

Something như thế này:

@GET 
@Path("getUserEntries") 
@Produces(MediaType.APPLICATION_JSON) 
public Response getUserEntries(@QueryParam("token") String token) {  
    String userId=getUserIdFromToken(token); 
    if (userId == null){ 
     return Response.status(Response.Status.UNAUTHORIZED).build(); 
    } else { 
     //get some data associated with that userId, put it in the response object and send it back 
     return Response.ok().entity(response).build(); 
    } 
} 

Tuy nhiên, những gì xảy ra nếu tôi có nhiều phương pháp mà cung cấp dữ liệu nếu chúng được gọi bởi một người dùng hợp lệ?

Tôi phải thực hiện việc kiểm tra này ở đầu mỗi phương pháp.

Tôi muốn làm cho quá trình cấp phép này trong suốt

Vì vậy, hai câu hỏi lớn ở đây:

  1. là thiết kế này ok? Toàn bộ xác thực với người dùng/pass, máy chủ tạo và lưu trữ và gửi mã thông báo cho người dùng, người dùng gửi mã thông báo về các yêu cầu trong tương lai.
  2. Tôi phải làm gì nếu tôi có nhiều điểm cuối cần xác định danh tính của người dùng đang gọi? Tôi có thể đánh dấu chúng bằng một số chú thích hay không, sử dụng một số nhà cung cấp bảo mật/trình xác thực (nơi tôi có thể thêm logic của riêng mình để xác thực - ví dụ: kiểm tra xem mã thông báo không cũ hơn 5 ngày, v.v.).

Cảm ơn

Trả lời

2

là thiết kế này ok? Toàn bộ xác thực với người dùng/pass, máy chủ tạo và lưu trữ và gửi mã thông báo cho người dùng, người dùng gửi mã thông báo về các yêu cầu trong tương lai.

Có phần OK. Mức độ khái niệm không quá tệ (miễn là bạn có quyền tự đăng ký) nhưng giao diện cần rất nhiều tinh chỉnh. Trong khi có, POST để đăng ký và đăng nhập là chính xác, đối với phần còn lại của webapp, bạn nên kéo thông tin nhận dạng ra khỏi ngữ cảnh nếu cần, và sử dụng điều khiển truy cập dựa trên vai trò ở cấp phương thức mà bạn có thể.

Lưu ý rằng vùng chứa của bạn có toàn bộ cơ chế xác thực và ủy quyền hỗ trợ được tích hợp sẵn. Hãy sử dụng chúng.

Tôi phải làm gì nếu tôi có nhiều điểm cuối cần xác định danh tính của người dùng đang gọi? Tôi có thể đánh dấu chúng bằng một số chú thích hay không, sử dụng một số nhà cung cấp bảo mật/trình xác thực (nơi tôi có thể thêm logic của riêng mình để xác thực - ví dụ: kiểm tra xem mã thông báo không cũ hơn 5 ngày, v.v.).

Họ có cần danh tính? Hay họ chỉ cần biết rằng người dùng được phép truy cập chúng? Nếu phương pháp sau, phương pháp đơn giản nhất là đặt chú thích @RolesAllowed phù hợp vào phương pháp, tại thời điểm đó (với cấu hình phù hợp; xem JEE5 security docs). Nếu trước đây, bạn cần nhận đối tượng HttpServletRequest cho hành động hiện tại và gọi phương thức getUserPrincipal() để nhận danh tính của người dùng (hoặc null nếu họ chưa đăng nhập). This SO question mô tả cách đi về nhận đối tượng yêu cầu; có một vài cách có thể để làm điều đó nhưng tôi khuyên bạn nên tiêm qua chú thích @Resource.

Điều tôi không làm là cho phép người dùng bình thường cung cấp danh tính của riêng họ qua @QueryParam; điều đó cực kỳ cởi mở với sự lạm dụng. Bạn có thể cho phép họ hỏi về người dùng khác theo cách đó, nhưng sau đó bạn cần phải quyết định xem bạn sẽ nói cho họ biết điều gì hay không dựa trên việc người dùng hiện tại có được phép biết bất kỳ điều gì về người dùng khác hay không. Đó là loại vấn đề bảo mật phức tạp xuất hiện trong ứng dụng thực và là điểm tốt để cần danh tính người dùng đã xác minh hiện tại.

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